PlanOpticon

planopticon / docs / guide / authentication.md
Source Blame History 525 lines
3551b80… noreply 1 # Authentication
3551b80… noreply 2
3551b80… noreply 3 PlanOpticon uses a unified authentication system to connect with cloud services for fetching recordings, documents, and other content. The system is **OAuth-first**: it prefers OAuth 2.0 flows for security and token management, but falls back to API keys when OAuth is not configured.
3551b80… noreply 4
3551b80… noreply 5 ## Auth strategy overview
3551b80… noreply 6
3551b80… noreply 7 PlanOpticon supports six cloud services out of the box: Google, Dropbox, Zoom, Notion, GitHub, and Microsoft. Each service uses the same authentication chain, implemented through the `OAuthManager` class. You configure credentials once (via environment variables or directly), and PlanOpticon handles token acquisition, storage, refresh, and fallback automatically.
3551b80… noreply 8
3551b80… noreply 9 All authentication state is managed through the `planopticon auth` CLI command, the `/auth` companion REPL command, or programmatically via the Python API.
3551b80… noreply 10
3551b80… noreply 11 ## The auth chain
3551b80… noreply 12
3551b80… noreply 13 When you authenticate with a service, PlanOpticon tries the following methods in order. It stops at the first one that succeeds:
3551b80… noreply 14
3551b80… noreply 15 1. **Saved token** -- Checks `~/.planopticon/{service}_token.json` for a previously saved token. If the token has not expired, it is used immediately. If it has expired but a refresh token is available, PlanOpticon attempts an automatic token refresh.
3551b80… noreply 16
3551b80… noreply 17 2. **Client Credentials grant** (Server-to-Server) -- If an `account_id` is configured (e.g., `ZOOM_ACCOUNT_ID`), PlanOpticon attempts a client credentials grant. This is a non-interactive flow suitable for automated pipelines and server-side integrations. No browser is required.
3551b80… noreply 18
3551b80… noreply 19 3. **OAuth 2.0 Authorization Code with PKCE** (interactive) -- If a client ID is configured and OAuth endpoints are available, PlanOpticon initiates an interactive OAuth PKCE flow. It opens a browser to the service's authorization page, waits for you to paste the authorization code, and exchanges it for tokens. The tokens are saved for future use.
3551b80… noreply 20
3551b80… noreply 21 4. **API key fallback** -- If no OAuth method succeeds, PlanOpticon checks for a service-specific API key environment variable (e.g., `GITHUB_TOKEN`, `NOTION_API_KEY`). This is the simplest setup but may have reduced capabilities compared to OAuth.
3551b80… noreply 22
3551b80… noreply 23 If none of the four methods succeed, PlanOpticon returns an error with hints about which environment variables to set.
3551b80… noreply 24
3551b80… noreply 25 ## Token storage
3551b80… noreply 26
3551b80… noreply 27 Tokens are persisted as JSON files in `~/.planopticon/`:
3551b80… noreply 28
3551b80… noreply 29 ```
3551b80… noreply 30 ~/.planopticon/
3551b80… noreply 31 google_token.json
3551b80… noreply 32 dropbox_token.json
3551b80… noreply 33 zoom_token.json
3551b80… noreply 34 notion_token.json
3551b80… noreply 35 github_token.json
3551b80… noreply 36 microsoft_token.json
3551b80… noreply 37 ```
3551b80… noreply 38
3551b80… noreply 39 Each token file contains:
3551b80… noreply 40
3551b80… noreply 41 | Field | Description |
3551b80… noreply 42 |-------|-------------|
3551b80… noreply 43 | `access_token` | The current access token |
3551b80… noreply 44 | `refresh_token` | Refresh token for automatic renewal (if provided by the service) |
3551b80… noreply 45 | `expires_at` | Unix timestamp when the token expires (with a 60-second safety margin) |
3551b80… noreply 46 | `client_id` | The client ID used for this token (for refresh) |
3551b80… noreply 47 | `client_secret` | The client secret used (for refresh) |
3551b80… noreply 48
3551b80… noreply 49 The `~/.planopticon/` directory is created automatically on first use. Token files are overwritten on each successful authentication or refresh.
3551b80… noreply 50
3551b80… noreply 51 To remove a saved token, use `planopticon auth <service> --logout` or delete the file directly.
3551b80… noreply 52
3551b80… noreply 53 ## Supported services
3551b80… noreply 54
3551b80… noreply 55 ### Google
3551b80… noreply 56
3551b80… noreply 57 Google authentication provides access to Google Drive and Google Docs for fetching documents, recordings, and other content.
3551b80… noreply 58
3551b80… noreply 59 **Scopes requested:**
3551b80… noreply 60
3551b80… noreply 61 - `https://www.googleapis.com/auth/drive.readonly`
3551b80… noreply 62 - `https://www.googleapis.com/auth/documents.readonly`
3551b80… noreply 63
3551b80… noreply 64 **Environment variables:**
3551b80… noreply 65
3551b80… noreply 66 | Variable | Required | Description |
3551b80… noreply 67 |----------|----------|-------------|
3551b80… noreply 68 | `GOOGLE_CLIENT_ID` | For OAuth | OAuth 2.0 Client ID from Google Cloud Console |
3551b80… noreply 69 | `GOOGLE_CLIENT_SECRET` | For OAuth | OAuth 2.0 Client Secret |
3551b80… noreply 70 | `GOOGLE_API_KEY` | Fallback | API key (limited access, no user-specific data) |
3551b80… noreply 71
3551b80… noreply 72 **OAuth app setup:**
3551b80… noreply 73
3551b80… noreply 74 1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
3551b80… noreply 75 2. Create a project (or select an existing one).
3551b80… noreply 76 3. Navigate to **APIs & Services > Credentials**.
3551b80… noreply 77 4. Click **Create Credentials > OAuth client ID**.
3551b80… noreply 78 5. Choose **Desktop app** as the application type.
3551b80… noreply 79 6. Copy the Client ID and Client Secret.
3551b80… noreply 80 7. Under **APIs & Services > Library**, enable the **Google Drive API** and **Google Docs API**.
3551b80… noreply 81 8. Set the environment variables:
3551b80… noreply 82
3551b80… noreply 83 ```bash
3551b80… noreply 84 export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
3551b80… noreply 85 export GOOGLE_CLIENT_SECRET="your-client-secret"
3551b80… noreply 86 ```
3551b80… noreply 87
3551b80… noreply 88 **Service account fallback:** For automated pipelines, you can use a Google service account instead of OAuth. Generate a service account key JSON file from the Google Cloud Console and set `GOOGLE_APPLICATION_CREDENTIALS` to point to it. The PlanOpticon Google Workspace connector (`planopticon gws`) uses the `gws` CLI which has its own auth flow via `gws auth login`.
3551b80… noreply 89
3551b80… noreply 90 ### Dropbox
3551b80… noreply 91
3551b80… noreply 92 Dropbox authentication provides access to files stored in Dropbox.
3551b80… noreply 93
3551b80… noreply 94 **Environment variables:**
3551b80… noreply 95
3551b80… noreply 96 | Variable | Required | Description |
3551b80… noreply 97 |----------|----------|-------------|
3551b80… noreply 98 | `DROPBOX_APP_KEY` | For OAuth | App key from the Dropbox App Console |
3551b80… noreply 99 | `DROPBOX_APP_SECRET` | For OAuth | App secret |
3551b80… noreply 100 | `DROPBOX_ACCESS_TOKEN` | Fallback | Long-lived access token (for quick setup) |
3551b80… noreply 101
3551b80… noreply 102 **OAuth app setup:**
3551b80… noreply 103
3551b80… noreply 104 1. Go to the [Dropbox App Console](https://www.dropbox.com/developers/apps).
3551b80… noreply 105 2. Click **Create App**.
3551b80… noreply 106 3. Choose **Scoped access** and **Full Dropbox** (or **App folder** for restricted access).
3551b80… noreply 107 4. Copy the App key and App secret from the **Settings** tab.
3551b80… noreply 108 5. Set the environment variables:
3551b80… noreply 109
3551b80… noreply 110 ```bash
3551b80… noreply 111 export DROPBOX_APP_KEY="your-app-key"
3551b80… noreply 112 export DROPBOX_APP_SECRET="your-app-secret"
3551b80… noreply 113 ```
3551b80… noreply 114
3551b80… noreply 115 **Access token shortcut:** For quick testing, you can generate an access token directly from the app's Settings page in the Dropbox App Console and set it as `DROPBOX_ACCESS_TOKEN`. This bypasses OAuth entirely but the token may have a limited lifetime.
3551b80… noreply 116
3551b80… noreply 117 ### Zoom
3551b80… noreply 118
3551b80… noreply 119 Zoom authentication provides access to cloud recordings, meeting metadata, and transcripts.
3551b80… noreply 120
3551b80… noreply 121 **Environment variables:**
3551b80… noreply 122
3551b80… noreply 123 | Variable | Required | Description |
3551b80… noreply 124 |----------|----------|-------------|
3551b80… noreply 125 | `ZOOM_CLIENT_ID` | For OAuth | OAuth client ID from the Zoom Marketplace |
3551b80… noreply 126 | `ZOOM_CLIENT_SECRET` | For OAuth | OAuth client secret |
3551b80… noreply 127 | `ZOOM_ACCOUNT_ID` | For S2S | Account ID for Server-to-Server OAuth |
3551b80… noreply 128
3551b80… noreply 129 **Server-to-Server (recommended for automation):**
3551b80… noreply 130
3551b80… noreply 131 When `ZOOM_ACCOUNT_ID` is set alongside `ZOOM_CLIENT_ID` and `ZOOM_CLIENT_SECRET`, PlanOpticon uses the client credentials grant (Server-to-Server OAuth). This is non-interactive and ideal for CI/CD pipelines and scheduled jobs.
3551b80… noreply 132
3551b80… noreply 133 1. Go to the [Zoom Marketplace](https://marketplace.zoom.us/).
3551b80… noreply 134 2. Click **Develop > Build App**.
3551b80… noreply 135 3. Choose **Server-to-Server OAuth**.
3551b80… noreply 136 4. Copy the Account ID, Client ID, and Client Secret.
3551b80… noreply 137 5. Add the required scopes: `recording:read:admin` (or `recording:read`).
3551b80… noreply 138 6. Set the environment variables:
3551b80… noreply 139
3551b80… noreply 140 ```bash
3551b80… noreply 141 export ZOOM_CLIENT_ID="your-client-id"
3551b80… noreply 142 export ZOOM_CLIENT_SECRET="your-client-secret"
3551b80… noreply 143 export ZOOM_ACCOUNT_ID="your-account-id"
3551b80… noreply 144 ```
3551b80… noreply 145
3551b80… noreply 146 **User-level OAuth PKCE:**
3551b80… noreply 147
3551b80… noreply 148 If `ZOOM_ACCOUNT_ID` is not set, PlanOpticon falls back to the interactive OAuth PKCE flow. This opens a browser window for the user to authorize access.
3551b80… noreply 149
3551b80… noreply 150 1. In the Zoom Marketplace, create a **General App** (or **OAuth** app).
3551b80… noreply 151 2. Set the redirect URI to `urn:ietf:wg:oauth:2.0:oob` (out-of-band).
3551b80… noreply 152 3. Copy the Client ID and Client Secret.
3551b80… noreply 153
3551b80… noreply 154 ### Notion
3551b80… noreply 155
3551b80… noreply 156 Notion authentication provides access to pages, databases, and content in your Notion workspace.
3551b80… noreply 157
3551b80… noreply 158 **Environment variables:**
3551b80… noreply 159
3551b80… noreply 160 | Variable | Required | Description |
3551b80… noreply 161 |----------|----------|-------------|
3551b80… noreply 162 | `NOTION_CLIENT_ID` | For OAuth | OAuth client ID from the Notion Integrations page |
3551b80… noreply 163 | `NOTION_CLIENT_SECRET` | For OAuth | OAuth client secret |
3551b80… noreply 164 | `NOTION_API_KEY` | Fallback | Internal integration token |
3551b80… noreply 165
3551b80… noreply 166 **OAuth app setup:**
3551b80… noreply 167
3551b80… noreply 168 1. Go to [My Integrations](https://www.notion.so/my-integrations) in Notion.
3551b80… noreply 169 2. Click **New integration**.
3551b80… noreply 170 3. Select **Public integration** (required for OAuth).
3551b80… noreply 171 4. Copy the OAuth Client ID and Client Secret.
3551b80… noreply 172 5. Set the redirect URI.
3551b80… noreply 173 6. Set the environment variables:
3551b80… noreply 174
3551b80… noreply 175 ```bash
3551b80… noreply 176 export NOTION_CLIENT_ID="your-client-id"
3551b80… noreply 177 export NOTION_CLIENT_SECRET="your-client-secret"
3551b80… noreply 178 ```
3551b80… noreply 179
3551b80… noreply 180 **Internal integration (API key fallback):**
3551b80… noreply 181
3551b80… noreply 182 For simpler setups, create an **Internal integration** from the Notion Integrations page. Copy the integration token and set it as `NOTION_API_KEY`. You must also share the relevant Notion pages/databases with the integration.
3551b80… noreply 183
3551b80… noreply 184 ```bash
3551b80… noreply 185 export NOTION_API_KEY="ntn_your-integration-token"
3551b80… noreply 186 ```
3551b80… noreply 187
3551b80… noreply 188 ### GitHub
3551b80… noreply 189
3551b80… noreply 190 GitHub authentication provides access to repositories, issues, and organization data.
3551b80… noreply 191
3551b80… noreply 192 **Scopes requested:**
3551b80… noreply 193
3551b80… noreply 194 - `repo`
3551b80… noreply 195 - `read:org`
3551b80… noreply 196
3551b80… noreply 197 **Environment variables:**
3551b80… noreply 198
3551b80… noreply 199 | Variable | Required | Description |
3551b80… noreply 200 |----------|----------|-------------|
3551b80… noreply 201 | `GITHUB_CLIENT_ID` | For OAuth | OAuth App client ID |
3551b80… noreply 202 | `GITHUB_CLIENT_SECRET` | For OAuth | OAuth App client secret |
3551b80… noreply 203 | `GITHUB_TOKEN` | Fallback | Personal access token (classic or fine-grained) |
3551b80… noreply 204
3551b80… noreply 205 **OAuth app setup:**
3551b80… noreply 206
3551b80… noreply 207 1. Go to **GitHub > Settings > Developer Settings > OAuth Apps**.
3551b80… noreply 208 2. Click **New OAuth App**.
3551b80… noreply 209 3. Set the Authorization callback URL to `urn:ietf:wg:oauth:2.0:oob`.
3551b80… noreply 210 4. Copy the Client ID and generate a Client Secret.
3551b80… noreply 211 5. Set the environment variables:
3551b80… noreply 212
3551b80… noreply 213 ```bash
3551b80… noreply 214 export GITHUB_CLIENT_ID="your-client-id"
3551b80… noreply 215 export GITHUB_CLIENT_SECRET="your-client-secret"
3551b80… noreply 216 ```
3551b80… noreply 217
3551b80… noreply 218 **Personal access token (recommended for most users):**
3551b80… noreply 219
3551b80… noreply 220 The simplest approach is to create a Personal Access Token:
3551b80… noreply 221
3551b80… noreply 222 1. Go to **GitHub > Settings > Developer Settings > Personal Access Tokens**.
3551b80… noreply 223 2. Generate a token with `repo` and `read:org` scopes.
3551b80… noreply 224 3. Set it as `GITHUB_TOKEN`:
3551b80… noreply 225
3551b80… noreply 226 ```bash
3551b80… noreply 227 export GITHUB_TOKEN="ghp_your-token"
3551b80… noreply 228 ```
3551b80… noreply 229
3551b80… noreply 230 ### Microsoft
3551b80… noreply 231
3551b80… noreply 232 Microsoft authentication provides access to Microsoft 365 resources via the Microsoft Graph API, including OneDrive, SharePoint, and Teams recordings.
3551b80… noreply 233
3551b80… noreply 234 **Scopes requested:**
3551b80… noreply 235
3551b80… noreply 236 - `https://graph.microsoft.com/OnlineMeetings.Read`
3551b80… noreply 237 - `https://graph.microsoft.com/Files.Read`
3551b80… noreply 238
3551b80… noreply 239 **Environment variables:**
3551b80… noreply 240
3551b80… noreply 241 | Variable | Required | Description |
3551b80… noreply 242 |----------|----------|-------------|
3551b80… noreply 243 | `MICROSOFT_CLIENT_ID` | For OAuth | Application (client) ID from Azure AD |
3551b80… noreply 244 | `MICROSOFT_CLIENT_SECRET` | For OAuth | Client secret from Azure AD |
3551b80… noreply 245
3551b80… noreply 246 **Azure AD app registration:**
3551b80… noreply 247
3551b80… noreply 248 1. Go to the [Azure Portal](https://portal.azure.com/).
3551b80… noreply 249 2. Navigate to **Azure Active Directory > App registrations**.
3551b80… noreply 250 3. Click **New registration**.
3551b80… noreply 251 4. Name the application (e.g., "PlanOpticon").
3551b80… noreply 252 5. Under **Supported account types**, select the appropriate option for your organization.
3551b80… noreply 253 6. Set the redirect URI to `urn:ietf:wg:oauth:2.0:oob` with platform **Mobile and desktop applications**.
3551b80… noreply 254 7. After registration, go to **Certificates & secrets** and create a new client secret.
3551b80… noreply 255 8. Under **API permissions**, add:
3551b80… noreply 256 - `OnlineMeetings.Read`
3551b80… noreply 257 - `Files.Read`
3551b80… noreply 258 9. Grant admin consent if required by your organization.
3551b80… noreply 259 10. Set the environment variables:
3551b80… noreply 260
3551b80… noreply 261 ```bash
3551b80… noreply 262 export MICROSOFT_CLIENT_ID="your-application-id"
3551b80… noreply 263 export MICROSOFT_CLIENT_SECRET="your-client-secret"
3551b80… noreply 264 ```
3551b80… noreply 265
3551b80… noreply 266 **Microsoft 365 CLI:** The `planopticon m365` commands use the `@pnp/cli-microsoft365` npm package, which has its own authentication flow via `m365 login`. This is separate from the OAuth flow described above.
3551b80… noreply 267
3551b80… noreply 268 ## CLI usage
3551b80… noreply 269
3551b80… noreply 270 ### `planopticon auth`
3551b80… noreply 271
3551b80… noreply 272 Authenticate with a cloud service or manage saved tokens.
3551b80… noreply 273
3551b80… noreply 274 ```
3551b80… noreply 275 planopticon auth SERVICE [--logout]
3551b80… noreply 276 ```
3551b80… noreply 277
3551b80… noreply 278 **Arguments:**
3551b80… noreply 279
3551b80… noreply 280 | Argument | Description |
3551b80… noreply 281 |----------|-------------|
3551b80… noreply 282 | `SERVICE` | One of: `google`, `dropbox`, `zoom`, `notion`, `github`, `microsoft` |
3551b80… noreply 283
3551b80… noreply 284 **Options:**
3551b80… noreply 285
3551b80… noreply 286 | Option | Description |
3551b80… noreply 287 |--------|-------------|
3551b80… noreply 288 | `--logout` | Clear the saved token for the specified service |
3551b80… noreply 289
3551b80… noreply 290 **Examples:**
3551b80… noreply 291
3551b80… noreply 292 ```bash
3551b80… noreply 293 # Authenticate with Google (triggers OAuth flow or uses saved token)
3551b80… noreply 294 planopticon auth google
3551b80… noreply 295
3551b80… noreply 296 # Authenticate with Zoom
3551b80… noreply 297 planopticon auth zoom
3551b80… noreply 298
3551b80… noreply 299 # Clear saved GitHub token
3551b80… noreply 300 planopticon auth github --logout
3551b80… noreply 301 ```
3551b80… noreply 302
3551b80… noreply 303 On success, the command prints the authentication method used:
3551b80… noreply 304
3551b80… noreply 305 ```
3551b80… noreply 306 Google authentication successful (oauth_pkce).
3551b80… noreply 307 ```
3551b80… noreply 308
3551b80… noreply 309 or
3551b80… noreply 310
3551b80… noreply 311 ```
3551b80… noreply 312 Github authentication successful (api_key).
3551b80… noreply 313 ```
3551b80… noreply 314
3551b80… noreply 315 ### Companion REPL `/auth`
3551b80… noreply 316
3551b80… noreply 317 Inside the interactive companion REPL (`planopticon -C` or `planopticon -I`), you can authenticate with services using the `/auth` command:
3551b80… noreply 318
3551b80… noreply 319 ```
3551b80… noreply 320 /auth SERVICE
3551b80… noreply 321 ```
3551b80… noreply 322
3551b80… noreply 323 Without arguments, `/auth` lists all available services:
3551b80… noreply 324
3551b80… noreply 325 ```
3551b80… noreply 326 > /auth
3551b80… noreply 327 Usage: /auth SERVICE
3551b80… noreply 328 Available: dropbox, github, google, microsoft, notion, zoom
3551b80… noreply 329 ```
3551b80… noreply 330
3551b80… noreply 331 With a service name, it runs the same auth chain as the CLI command:
3551b80… noreply 332
3551b80… noreply 333 ```
3551b80… noreply 334 > /auth github
3551b80… noreply 335 Github authentication successful (api_key).
3551b80… noreply 336 ```
3551b80… noreply 337
3551b80… noreply 338 ## Environment variables reference
3551b80… noreply 339
3551b80… noreply 340 The following table summarizes all environment variables used by the authentication system:
3551b80… noreply 341
3551b80… noreply 342 | Service | OAuth Client ID | OAuth Client Secret | API Key / Token | Account ID |
3551b80… noreply 343 |---------|----------------|--------------------|--------------------|------------|
3551b80… noreply 344 | Google | `GOOGLE_CLIENT_ID` | `GOOGLE_CLIENT_SECRET` | `GOOGLE_API_KEY` | -- |
3551b80… noreply 345 | Dropbox | `DROPBOX_APP_KEY` | `DROPBOX_APP_SECRET` | `DROPBOX_ACCESS_TOKEN` | -- |
3551b80… noreply 346 | Zoom | `ZOOM_CLIENT_ID` | `ZOOM_CLIENT_SECRET` | -- | `ZOOM_ACCOUNT_ID` |
3551b80… noreply 347 | Notion | `NOTION_CLIENT_ID` | `NOTION_CLIENT_SECRET` | `NOTION_API_KEY` | -- |
3551b80… noreply 348 | GitHub | `GITHUB_CLIENT_ID` | `GITHUB_CLIENT_SECRET` | `GITHUB_TOKEN` | -- |
3551b80… noreply 349 | Microsoft | `MICROSOFT_CLIENT_ID` | `MICROSOFT_CLIENT_SECRET` | -- | -- |
3551b80… noreply 350
3551b80… noreply 351 ## Python API
3551b80… noreply 352
3551b80… noreply 353 ### AuthConfig
3551b80… noreply 354
3551b80… noreply 355 The `AuthConfig` dataclass defines the authentication configuration for a service. It holds OAuth endpoints, credential references, scopes, and token storage paths.
3551b80… noreply 356
3551b80… noreply 357 ```python
3551b80… noreply 358 from video_processor.auth import AuthConfig
3551b80… noreply 359
3551b80… noreply 360 config = AuthConfig(
3551b80… noreply 361 service="myservice",
3551b80… noreply 362 oauth_authorize_url="https://example.com/oauth/authorize",
3551b80… noreply 363 oauth_token_url="https://example.com/oauth/token",
3551b80… noreply 364 client_id_env="MYSERVICE_CLIENT_ID",
3551b80… noreply 365 client_secret_env="MYSERVICE_CLIENT_SECRET",
3551b80… noreply 366 api_key_env="MYSERVICE_API_KEY",
3551b80… noreply 367 scopes=["read", "write"],
3551b80… noreply 368 )
3551b80… noreply 369 ```
3551b80… noreply 370
3551b80… noreply 371 **Key fields:**
3551b80… noreply 372
3551b80… noreply 373 | Field | Type | Description |
3551b80… noreply 374 |-------|------|-------------|
3551b80… noreply 375 | `service` | `str` | Service identifier (used for token filename) |
3551b80… noreply 376 | `oauth_authorize_url` | `Optional[str]` | OAuth authorization endpoint |
3551b80… noreply 377 | `oauth_token_url` | `Optional[str]` | OAuth token endpoint |
3551b80… noreply 378 | `client_id` / `client_id_env` | `Optional[str]` | Client ID value or env var name |
3551b80… noreply 379 | `client_secret` / `client_secret_env` | `Optional[str]` | Client secret value or env var name |
3551b80… noreply 380 | `api_key_env` | `Optional[str]` | Environment variable for API key fallback |
3551b80… noreply 381 | `scopes` | `List[str]` | OAuth scopes to request |
3551b80… noreply 382 | `redirect_uri` | `str` | Redirect URI (default: `urn:ietf:wg:oauth:2.0:oob`) |
3551b80… noreply 383 | `account_id` / `account_id_env` | `Optional[str]` | Account ID for client credentials grant |
3551b80… noreply 384 | `token_path` | `Optional[Path]` | Override token storage path |
3551b80… noreply 385
3551b80… noreply 386 **Resolved properties:**
3551b80… noreply 387
3551b80… noreply 388 - `resolved_client_id` -- Returns the client ID from the direct value or environment variable.
3551b80… noreply 389 - `resolved_client_secret` -- Returns the client secret from the direct value or environment variable.
3551b80… noreply 390 - `resolved_api_key` -- Returns the API key from the environment variable.
3551b80… noreply 391 - `resolved_account_id` -- Returns the account ID from the direct value or environment variable.
3551b80… noreply 392 - `resolved_token_path` -- Returns the token file path (default: `~/.planopticon/{service}_token.json`).
3551b80… noreply 393 - `supports_oauth` -- Returns `True` if both OAuth endpoints are configured.
3551b80… noreply 394
3551b80… noreply 395 ### OAuthManager
3551b80… noreply 396
3551b80… noreply 397 The `OAuthManager` class manages the full authentication lifecycle for a service.
3551b80… noreply 398
3551b80… noreply 399 ```python
3551b80… noreply 400 from video_processor.auth import OAuthManager, AuthConfig
3551b80… noreply 401
3551b80… noreply 402 config = AuthConfig(
3551b80… noreply 403 service="notion",
3551b80… noreply 404 oauth_authorize_url="https://api.notion.com/v1/oauth/authorize",
3551b80… noreply 405 oauth_token_url="https://api.notion.com/v1/oauth/token",
3551b80… noreply 406 client_id_env="NOTION_CLIENT_ID",
3551b80… noreply 407 client_secret_env="NOTION_CLIENT_SECRET",
3551b80… noreply 408 api_key_env="NOTION_API_KEY",
3551b80… noreply 409 scopes=["read_content"],
3551b80… noreply 410 )
3551b80… noreply 411 manager = OAuthManager(config)
3551b80… noreply 412
3551b80… noreply 413 # Full auth chain -- returns AuthResult
3551b80… noreply 414 result = manager.authenticate()
3551b80… noreply 415 if result.success:
3551b80… noreply 416 print(f"Authenticated via {result.method}")
3551b80… noreply 417 print(f"Token: {result.access_token[:20]}...")
3551b80… noreply 418
3551b80… noreply 419 # Convenience method -- returns just the token string or None
3551b80… noreply 420 token = manager.get_token()
3551b80… noreply 421
3551b80… noreply 422 # Clear saved token (logout)
3551b80… noreply 423 manager.clear_token()
3551b80… noreply 424 ```
3551b80… noreply 425
3551b80… noreply 426 **AuthResult fields:**
3551b80… noreply 427
3551b80… noreply 428 | Field | Type | Description |
3551b80… noreply 429 |-------|------|-------------|
3551b80… noreply 430 | `success` | `bool` | Whether authentication succeeded |
3551b80… noreply 431 | `access_token` | `Optional[str]` | The access token (if successful) |
3551b80… noreply 432 | `method` | `Optional[str]` | One of: `saved_token`, `oauth_pkce`, `client_credentials`, `api_key` |
3551b80… noreply 433 | `expires_at` | `Optional[float]` | Token expiry as a Unix timestamp |
3551b80… noreply 434 | `refresh_token` | `Optional[str]` | Refresh token (if provided) |
3551b80… noreply 435 | `error` | `Optional[str]` | Error message (if unsuccessful) |
3551b80… noreply 436
3551b80… noreply 437 ### Pre-built configs
3551b80… noreply 438
3551b80… noreply 439 PlanOpticon ships with pre-built `AuthConfig` instances for all six supported services. Access them via convenience functions:
3551b80… noreply 440
3551b80… noreply 441 ```python
3551b80… noreply 442 from video_processor.auth import get_auth_config, get_auth_manager
3551b80… noreply 443
3551b80… noreply 444 # Get just the config
3551b80… noreply 445 config = get_auth_config("zoom")
3551b80… noreply 446
3551b80… noreply 447 # Get a ready-to-use manager
3551b80… noreply 448 manager = get_auth_manager("github")
3551b80… noreply 449 token = manager.get_token()
3551b80… noreply 450 ```
3551b80… noreply 451
3551b80… noreply 452 ### Building custom connectors
3551b80… noreply 453
3551b80… noreply 454 To add authentication for a new service, create an `AuthConfig` with the service's OAuth endpoints and credential environment variables:
3551b80… noreply 455
3551b80… noreply 456 ```python
3551b80… noreply 457 from video_processor.auth import AuthConfig, OAuthManager
3551b80… noreply 458
3551b80… noreply 459 config = AuthConfig(
3551b80… noreply 460 service="slack",
3551b80… noreply 461 oauth_authorize_url="https://slack.com/oauth/v2/authorize",
3551b80… noreply 462 oauth_token_url="https://slack.com/api/oauth.v2.access",
3551b80… noreply 463 client_id_env="SLACK_CLIENT_ID",
3551b80… noreply 464 client_secret_env="SLACK_CLIENT_SECRET",
3551b80… noreply 465 api_key_env="SLACK_BOT_TOKEN",
3551b80… noreply 466 scopes=["channels:read", "channels:history"],
3551b80… noreply 467 )
3551b80… noreply 468
3551b80… noreply 469 manager = OAuthManager(config)
3551b80… noreply 470 result = manager.authenticate()
3551b80… noreply 471 ```
3551b80… noreply 472
3551b80… noreply 473 The token will be saved to `~/.planopticon/slack_token.json` and automatically refreshed on subsequent calls.
3551b80… noreply 474
3551b80… noreply 475 ## Troubleshooting
3551b80… noreply 476
3551b80… noreply 477 ### "No auth method available for {service}"
3551b80… noreply 478
3551b80… noreply 479 This means none of the four auth methods succeeded. Check that:
3551b80… noreply 480
3551b80… noreply 481 - The required environment variables are set and non-empty.
3551b80… noreply 482 - For OAuth: both the client ID and client secret (or app key/secret) are set.
3551b80… noreply 483 - For API key fallback: the correct environment variable is set.
3551b80… noreply 484
3551b80… noreply 485 The error message includes hints about which variables to set.
3551b80… noreply 486
3551b80… noreply 487 ### Token refresh fails
3551b80… noreply 488
3551b80… noreply 489 If automatic token refresh fails, PlanOpticon falls back to the next auth method in the chain. Common causes:
3551b80… noreply 490
3551b80… noreply 491 - The refresh token has been revoked (e.g., you changed your password or revoked app access).
3551b80… noreply 492 - The OAuth app's client secret has changed.
3551b80… noreply 493 - The service requires re-authorization after a certain period.
3551b80… noreply 494
3551b80… noreply 495 To resolve, clear the token and re-authenticate:
3551b80… noreply 496
3551b80… noreply 497 ```bash
3551b80… noreply 498 planopticon auth google --logout
3551b80… noreply 499 planopticon auth google
3551b80… noreply 500 ```
3551b80… noreply 501
3551b80… noreply 502 ### OAuth PKCE flow does not open a browser
3551b80… noreply 503
3551b80… noreply 504 If the browser does not open automatically, PlanOpticon prints the authorization URL to the terminal. Copy and paste it into your browser manually. After authorizing, paste the authorization code back into the terminal prompt.
3551b80… noreply 505
3551b80… noreply 506 ### "requests not installed"
3551b80… noreply 507
3551b80… noreply 508 The OAuth flows require the `requests` library. It is included as a dependency of PlanOpticon, but if you installed PlanOpticon in a minimal environment, install it manually:
3551b80… noreply 509
3551b80… noreply 510 ```bash
3551b80… noreply 511 pip install requests
3551b80… noreply 512 ```
3551b80… noreply 513
3551b80… noreply 514 ### Permission denied on token file
3551b80… noreply 515
3551b80… noreply 516 PlanOpticon needs write access to `~/.planopticon/`. If the directory or token files have restrictive permissions, adjust them:
3551b80… noreply 517
3551b80… noreply 518 ```bash
3551b80… noreply 519 chmod 700 ~/.planopticon
3551b80… noreply 520 chmod 600 ~/.planopticon/*_token.json
3551b80… noreply 521 ```
3551b80… noreply 522
3551b80… noreply 523 ### Microsoft authentication uses the `/common` tenant
3551b80… noreply 524
3551b80… noreply 525 The default Microsoft OAuth configuration uses the `common` tenant endpoint (`login.microsoftonline.com/common/...`), which supports both personal Microsoft accounts and Azure AD organizational accounts. If your organization requires a specific tenant, you can create a custom `AuthConfig` with the tenant-specific URLs.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button