본문으로 건너뛰기
cccskills
무료GitHub에 공개

oauth-providers

Debug OAuth sign-in failures and add new OAuth providers to Keating (web + CLI). Use when a provider's "Sign in with …" flow fails, when adding a new OAuth provider, or when changing redirect URIs, token exchange, or refresh behavior.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating스타 36(GitHub 36 + cccskills 0)
연동 도구X (Twitter)OpenAI

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

OAuth providers in Keating

How OAuth sign-in works in this repo, the provider-specific quirks that have already caused bugs, and the checklist for adding a new provider.

Architecture

The web app uses an authorization-code + PKCE flow, brokered through the Nitro server so tokens are exchanged server-side:

PieceFileRole
Provider registryweb/src/keating/oauth.ts (OAUTH_PROVIDERS)Client IDs, authorize/token URLs, scopes, redirect URIs, extra authorize params
Redirect resolutionweb/src/keating/oauth.ts (resolveOAuthRedirectUri)Prod (keating.help) → https://keating.help/oauth/callback; everywhere else → the provider's CLI loopback URI + manual paste
Popup + pending stateweb/src/keating/oauth.ts (initiateOAuth)Saves {verifier, state, redirectUri} to localStorage under keating_oauth_pending, opens the authorize popup
Callback pageweb/src/pages/OAuthCallback.tsx (route /oauth/callback)Runs completeOAuthFromInput(location.href), posts keating-oauth-result message to the opener
Manual paste inputweb/src/components/settings/CloudProviderKeysSection.tsxShown while sign-in is pending; accepts a pasted callback URL, code#state, query string, or bare code
Token exchangeweb/server/api/oauth/token.tsPOSTs to the provider's token URL with the stored verifier
Token refreshweb/server/api/oauth/refresh.tsAuto-refresh 60s before expiry; 401/403 deletes stored credentials
Server client configweb/server/api/oauth/config.tsClient IDs/secrets, env-overridable (OAUTH_<PROVIDER>_CLIENT_ID / _SECRET)
Consumptionweb/src/lib/provider-models.ts (getProviderApiKey)OAuth token (or exchanged API key) wins over stored API keys
Reference implementationweb/node_modules/@earendil-works/pi-ai/dist/utils/oauth/*.jsThe CLI's working flows — check here first when a web flow misbehaves

Credentials are stored per provider as JSON under the oauth:<id> key in getAppStorage().providerKeys. Provider-name aliasing (openai → openai-codex, google → google-gemini-cli) lives in providerToOAuthId.

After editing web/src/keating/oauth.ts, regenerate the sandbox snapshot: bun scripts/generate-nodepod-boot-files.ts.

Provider quirks (hard-won; do not regress)

Anthropic (client 9d1c250a-e61b-44d9-88ed-5944d1962f5e, Codex Pro/Max):

  • The token endpoint https://platform.Codex.com/v1/oauth/token only accepts JSON bodies (Content-Type: application/json), for both code exchange and refresh. Form-urlencoded fails. This is special-cased in token.ts and refresh.ts.
  • Uses the provider-hosted code-display callback (https://platform.Codex.com/oauth/code/callback) in all environments; the user copies a code#state string. code=true must be in the authorize params or the code is never displayed.
  • state must equal the PKCE verifier (not a random value), and must be sent in the token exchange body.
  • Resulting sk-ant-oat-* access tokens are handled downstream by pi-ai (Bearer + anthropic-beta: oauth-2025-04-20 headers) — pass them through as the "apiKey"; do not put them in x-api-key yourself.

OpenAI Codex (client app_EMoamEEZ73f0CkXaXp7hrann, ChatGPT Plus/Pro):

  • Only http://localhost:1455/auth/callback is registered; any web-origin redirect is rejected at the authorize step (unless keating.help is registered on the client used — see redirect resolution above).
  • Form-urlencoded token exchange is correct here.
  • After exchange, the id_token is swapped for a real OpenAI API key via a token-exchange grant (web/server/api/oauth/openai-codex.ts, requested_token: openai-api-key).
  • Authorize needs id_token_add_organizations=true, codex_cli_simplified_flow=true, originator.

Google Gemini CLI (client 681255809395-oo8f…, installed app):

  • Installed-app clients accept any localhost port as redirect but no https origins, and the token exchange requires the client secret — the Gemini CLI's secret is public by design (embedded in its open-source repo; Google docs say installed-app secrets are not confidential) and is the fallback in web/server/api/oauth/config.ts.
  • Authorize needs access_type=offline&prompt=consent or no refresh token is returned.

Debugging a failing sign-in

  1. Reproduce and note which step fails:
    • Error on the provider's authorize page → redirect URI not registered for that client, or missing required authorize params.
    • "Token exchange failed: 502 …" from the app → server-side exchange rejected; check the Nitro log line [oauth/token] <provider> token exchange failed: <status> <body> for the upstream error.
    • Signed in but requests 401 → token consumed incorrectly (see quirks), or refresh failing ([oauth/refresh] log).
  2. Diff the failing flow against the CLI's pi-ai implementation (node_modules/@earendil-works/pi-ai/dist/utils/oauth/) — encoding (JSON vs form), authorize params, state semantics, redirect URI. Every web bug so far has been a divergence from those reference flows.
  3. Fix in the smallest layer (registry vs server handler), then run cd web && bun test src/test/oauth.test.ts && bunx tsc --noEmit.

Adding a new provider

  1. Add the entry to OAUTH_PROVIDERS in web/src/keating/oauth.ts (extend OAuthProviderId). Set redirectUri if the client only accepts a fixed loopback URI; leave it unset to use the web callback.
  2. Add server client config in web/server/api/oauth/config.ts (extend OAuthServerProviderId), with env overrides. Note the token body encoding the provider expects — special-case in token.ts/refresh.ts if not form-urlencoded.
  3. Map the app-facing provider name in providerToOAuthId and oauthProviderToProviderNames (CloudProviderKeysSection), and add a label to OAUTH_PROVIDER_LABELS.
  4. Wire consumption: confirm getProviderApiKey returns something the model client can use; if the provider needs a secondary exchange (like Codex → API key), do it server-side after the token response.
  5. Tests in web/src/test/oauth.test.ts: provider wiring, redirect URI resolution (prod + dev), and any exchange encoding special case.
  6. Regenerate nodepod boot files; run cd web && bun test && bunx tsc --noEmit.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when the user wants to learn, be taught, be quizzed, or understand an idea across any domain — science, math, philosophy, code, law, politics, psychology, medicine, arts, or history — with active scaffolding.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

ax

무료

This skill helps with using the @ax-llm/ax TypeScript library for building LLM applications. Use when the user asks about ax(), ai(), f(), s(), agent(), flow(), AxGen, AxAgent, AxFlow, signatures, streaming, or mentions @ax-llm/ax.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

ax-agent

무료

This skill helps an LLM generate correct AxAgent code using @ax-llm/ax. Use when the user asks about agent(), child agents, namespaced functions, discovery mode, shared fields, llmQuery(...), RLM code execution, recursionOptions, or agent runtime behavior. For tuning and eval with agent.optimize(...), use ax-agent-optimize.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

This skill helps an LLM generate correct AxAgent tuning and evaluation code using @ax-llm/ax. Use when the user asks about agent.optimize(...), judgeOptions, eval datasets, optimization targets, saved optimizedProgram artifacts, or recursive optimization guidance.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

ax-ai

무료

This skill helps an LLM generate correct AI provider setup and configuration code using @ax-llm/ax. Use when the user asks about ai(), providers, models, presets, embeddings, extended thinking, context caching, or mentions OpenAI/Anthropic/Google/Azure/Groq/DeepSeek/Mistral/Cohere/Together/Ollama/HuggingFace/Reka/OpenRouter with @ax-llm/ax.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

ax-flow

무료

This skill helps an LLM generate correct AxFlow workflow code using @ax-llm/ax. Use when the user asks about flow(), AxFlow, workflow orchestration, parallel execution, DAG workflows, conditional routing, map/reduce patterns, or multi-node AI pipelines.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Diogenesoftoronto/keating362026년 10월 20일 업데이트

Diogenesoftoronto의 스킬 모두 보기

이 스킬의 문제 신고