{"id":48145468,"url":"https://github.com/withoneai/auth","last_synced_at":"2026-05-02T22:02:03.159Z","repository":{"id":346822299,"uuid":"1189205579","full_name":"withoneai/auth","owner":"withoneai","description":"A drop-in authentication widget that lets your users connect their third-party apps to your application.","archived":false,"fork":false,"pushed_at":"2026-04-23T17:32:20.000Z","size":260,"stargazers_count":6,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-28T15:43:02.899Z","etag":null,"topics":["agents","auth","integrations"],"latest_commit_sha":null,"homepage":"https://withone.ai/products/auth","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/withoneai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T04:44:58.000Z","updated_at":"2026-04-23T17:31:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/withoneai/auth","commit_stats":null,"previous_names":["withoneai/auth"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/withoneai/auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withoneai%2Fauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withoneai%2Fauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withoneai%2Fauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withoneai%2Fauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/withoneai","download_url":"https://codeload.github.com/withoneai/auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withoneai%2Fauth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32550914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T21:31:48.061Z","status":"ssl_error","status_checked_at":"2026-05-02T21:31:46.574Z","response_time":132,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","auth","integrations"],"created_at":"2026-04-04T16:58:27.260Z","updated_at":"2026-05-02T22:02:03.153Z","avatar_url":"https://github.com/withoneai.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://assets.withone.ai/banners/auth.png\" alt=\"One Auth — Connect your users to every app with a drop-in auth widget.\" style=\"border-radius: 5px;\"\u003e\n\n\u003ch3 align=\"center\"\u003eOne Auth\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://withone.ai\"\u003e\u003cstrong\u003eWebsite\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://withone.ai/docs/auth\"\u003e\u003cstrong\u003eDocs\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://app.withone.ai\"\u003e\u003cstrong\u003eDashboard\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://withone.ai/changelog\"\u003e\u003cstrong\u003eChangelog\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://x.com/withoneai\"\u003e\u003cstrong\u003eX\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://linkedin.com/company/withoneai\"\u003e\u003cstrong\u003eLinkedIn\u003c/strong\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.com/package/@withone/auth\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/%40withone%2Fauth\" alt=\"npm version\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nOne Auth is a pre-built, embeddable authentication UI that makes it easy for your users to securely connect their third-party accounts (Gmail, Slack, Salesforce, QuickBooks, etc.) directly within your application.\n\nFully compatible with popular frameworks such as React, Next.js, Vue, Svelte, and more.\n\n## Install\n\nWith npm:\n\n```bash\nnpm i @withone/auth\n```\n\nWith yarn:\n\n```bash\nyarn add @withone/auth\n```\n\n## Getting Started with the Skill\n\nThe easiest way to integrate One Auth is by installing the skill for your AI coding agent. The skill provides step-by-step guidance for setting up the backend token endpoint, frontend component, and connection handling.\n\n```bash\nnpx skills add withoneai/auth\n```\n\nOnce installed, your AI coding agent will have full context on how to set up and work with One Auth in your project.\n\n## Using the Auth component\n\nReplace the `token URL` with your backend token endpoint URL.\n\n\u003e ⚠️ **Must be a full URL** — relative paths like `/api/one-auth` won't work because the Auth widget runs in an iframe on a different domain. Use the complete URL (e.g., `https://your-domain.com/api/one-auth`).\n\n```tsx\n\"use client\";\n\nimport { useOneAuth } from \"@withone/auth\";\n\nconst USER_ID = \"your-user-uuid\";\n\nexport function ConnectIntegrationButton() {\n  const { open } = useOneAuth({\n    token: {\n      url: \"https://your-domain.com/api/one-auth\",\n      headers: {\n        \"x-user-id\": USER_ID,\n      },\n    },\n    onSuccess: (connection) =\u003e {\n      console.log(\"Connection created:\", connection);\n    },\n    onError: (error) =\u003e {\n      console.error(\"Connection failed:\", error);\n    },\n    onClose: () =\u003e {\n      console.log(\"Auth modal closed\");\n    },\n  });\n\n  return \u003cbutton onClick={open}\u003eConnect Integration\u003c/button\u003e;\n}\n```\n\n### Configuration Options\n\n| Option | Type | Description |\n|---|---|---|\n| `token.url` | `string` | Full URL of your backend token endpoint |\n| `token.headers` | `object` | Headers to send with the token request (e.g., user ID) |\n| `selectedConnection` | `string` | Pre-select an integration by display name (e.g., `\"Gmail\"`) |\n| `appTheme` | `\"dark\" \\| \"light\"` | Theme for the Auth modal |\n| `title` | `string` | Custom title for the modal |\n| `imageUrl` | `string` | Custom logo URL to display in the modal |\n| `companyName` | `string` | Your company name to display in the modal |\n| `authWindow` | `\"same\" \\| \"popup\"` | How the OAuth provider is opened. Defaults to `\"same\"` (top-level redirect, returns to the original page). Pass `\"popup\"` to open in a separate window instead. |\n| `onSuccess` | `(connection) =\u003e void` | Callback when a connection is successfully created |\n| `onError` | `(error) =\u003e void` | Callback when the connection fails |\n| `onClose` | `() =\u003e void` | Callback when the modal is closed |\n\n### Auth window mode\n\nBy default the OAuth provider opens via a top-level redirect (`authWindow: \"same\"`) and returns the user to your page when they finish — this avoids popup blockers and works reliably across mobile browsers.\n\nIf a full-page redirect doesn't fit your app (e.g. you'd lose unsaved state), pass `authWindow: \"popup\"` to open the provider in a separate window instead:\n\n```tsx\nconst { open } = useOneAuth({\n  token: { url: \"https://your-domain.com/api/one-auth\" },\n  authWindow: \"popup\",\n  onSuccess: (connection) =\u003e console.log(connection),\n});\n```\n\n## Backend Token Generation\n\nTo enable Auth connections, your backend needs an endpoint that generates a session token by calling the One API.\n\n### Environment Variables\n\n```env\nONE_SECRET_KEY=sk_test_your_secret_key_here\n```\n\n| Variable | Description |\n|---|---|\n| `ONE_SECRET_KEY` | Your secret key from the [One dashboard](https://app.withone.ai/settings/api-keys) |\n\n### API Route — `POST /api/one-auth`\n\nYour backend endpoint should:\n\n1. Extract the `x-user-id` header to identify the user\n2. Handle pagination — the Auth widget sends `page` and `limit` as query parameters\n3. Call `POST https://api.withone.ai/v1/authkit/token` with your secret key and the user's identity\n4. Return the token response to the client\n\n**Request headers:**\n\n| Header | Required | Description |\n|---|---|---|\n| `x-user-id` | Yes | Unique identifier for the user (e.g., UUID from your auth system) |\n\n**Query parameters (sent automatically by the widget):**\n\n| Parameter | Description |\n|---|---|\n| `page` | Current page number for paginated integration list |\n| `limit` | Number of integrations per page |\n\n**Example implementation (Next.js):**\n\n```typescript\nimport { NextRequest, NextResponse } from \"next/server\";\n\nconst corsHeaders = {\n  \"Access-Control-Allow-Origin\": \"*\",\n  \"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n  \"Access-Control-Allow-Headers\": \"Content-Type, Authorization, x-user-id\",\n};\n\nexport async function OPTIONS() {\n  return NextResponse.json({}, { headers: corsHeaders });\n}\n\nexport async function POST(req: NextRequest) {\n  try {\n    const userId = req.headers.get(\"x-user-id\");\n\n    if (!userId) {\n      return NextResponse.json(\n        { error: \"Unauthorized\" },\n        { status: 401, headers: corsHeaders }\n      );\n    }\n\n    // The Auth widget sends pagination params as query parameters\n    const page = req.nextUrl.searchParams.get(\"page\");\n    const limit = req.nextUrl.searchParams.get(\"limit\");\n\n    const response = await fetch(\n      `https://api.withone.ai/v1/authkit/token?page=${page}\u0026limit=${limit}`,\n      {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n          \"X-One-Secret\": process.env.ONE_SECRET_KEY!,\n        },\n        body: JSON.stringify({\n          identity: userId,\n          identityType: \"user\", // \"user\" | \"team\" | \"organization\" | \"project\"\n        }),\n      }\n    );\n\n    if (!response.ok) {\n      return NextResponse.json(\n        { error: \"Failed to generate token\" },\n        { status: response.status, headers: corsHeaders }\n      );\n    }\n\n    const token = await response.json();\n    return NextResponse.json(token, { headers: corsHeaders });\n  } catch (error) {\n    return NextResponse.json(\n      { error: \"Failed to generate token\" },\n      { status: 500, headers: corsHeaders }\n    );\n  }\n}\n```\n\n**Success response (200):**\n\n```json\n{\n  \"rows\": [\n    {\n      \"id\": 41596,\n      \"connectionDefId\": 34,\n      \"type\": \"api\",\n      \"title\": \"ActiveCampaign\",\n      \"image\": \"https://assets.withone.ai/connectors/activecampaign.svg\",\n      \"environment\": \"test\",\n      \"tags\": [],\n      \"active\": true\n    },\n    {\n      \"id\": 41524,\n      \"connectionDefId\": 109,\n      \"type\": \"api\",\n      \"title\": \"Anthropic\",\n      \"image\": \"https://assets.withone.ai/connectors/anthropic.svg\",\n      \"environment\": \"test\",\n      \"tags\": [],\n      \"active\": true\n    }\n  ],\n  \"total\": 247,\n  \"pages\": 3,\n  \"page\": 1,\n  \"requestId\": 110256\n}\n```\n\nThe response includes a paginated list of available integrations. The widget handles pagination automatically by calling your token endpoint with different `page` values.\n\n## Configuration \u0026 Management\n\nAll configuration for the Auth component is managed via the **[One Dashboard](https://app.withone.ai/settings/authkit)**. From the dashboard, you can:\n\n- **Choose which apps are visible** — Select which integrations appear in the Auth modal for your users\n- **Configure OAuth credentials** — Use One's default client ID and client secret, or bring your own for any integration\n- **Adjust scopes** — Customize the OAuth scopes requested for each integration\n\nAuthKit configuration is scoped at the **project level**, enabling multi-tenant architecture. Each project in your One account can have its own set of visible apps, OAuth credentials, and scopes — allowing you to serve different configurations to different products or customer segments from a single account.\n\n\u003e **Dashboard link:** [app.withone.ai/settings/authkit](https://app.withone.ai/settings/authkit)\n\n## Diagram\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant YourApp as Your Application\n    participant YourBackend as Your Backend\n    participant One as One Auth\n    participant Integration as Third-party Integration\n\n    User-\u003e\u003eYourApp: Clicks \"Connect Integration\"\n    YourApp-\u003e\u003eOne: Open Auth modal\n    One-\u003e\u003eYourBackend: Request Auth token (page=1\u0026limit=100)\n    YourBackend-\u003e\u003eOne: Generate token with user identity\n    One-\u003e\u003eOne: Display integrations list\n    User-\u003e\u003eOne: Select integration \u0026 authenticate\n    One-\u003e\u003eIntegration: OAuth handshake\n    Integration-\u003e\u003eOne: Access token\n    One-\u003e\u003eOne: Store encrypted credentials\n    One-\u003e\u003eYourApp: Return connection details\n    YourApp-\u003e\u003eUser: Connection successful!\n```\n\n## License\n\nThis project is licensed under the GPL-3.0 license. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithoneai%2Fauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwithoneai%2Fauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithoneai%2Fauth/lists"}