npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@partme.ai/openclaw-oauth2

v2026.7.1

Published

Standard OAuth2/OIDC client reverse proxy for OpenClaw, powered by openid-client

Readme

OpenClaw OAuth2

基于 openid-client 的标准 OAuth2/OIDC Client 鉴权代理。插件在 OpenClaw Gateway 前启动 HTTP/WebSocket 反向代理,完成外部授权、会话管理、Bearer Token 校验,并向 trusted-proxy 注入可信用户信息。

支持能力

  • OAuth2/OIDC Discovery 或显式端点配置
  • Authorization Code + PKCE S256
  • Refresh Token、Token Revocation
  • UserInfo 或 Token Introspection
  • HttpOnly/SameSite/Secure Session Cookie
  • Redis 共享 state/session,支持多实例
  • HTTP 与 WebSocket trusted-proxy 转发
  • 可通过 requiredScopes 要求外部 Access Token 必须包含指定 Scope

插件不包含任何厂商专用实现。Auth0、Keycloak、Azure AD 或其他标准服务都通过同一组配置接入。

授权与代理架构

浏览器 ──▶ OAuth2 代理 ──302──▶ 外部 OAuth2/OIDC Server
  ▲             │                         │
  │             │ callback(code + state) ◀┘
  │             ▼
  │      PKCE 换 Token / UserInfo ──▶ HttpOnly Session
  │             │
  └── HTTP/WS ──┼──▶ Scope / 过期 / 刷新校验
                │
                ▼ 覆盖可信身份 Header
        loopback OpenClaw Gateway(trusted-proxy)
sequenceDiagram
    participant Browser as 浏览器
    participant Proxy as OAuth2 插件代理
    participant IdP as 外部 OAuth2/OIDC Server
    participant Gateway as OpenClaw Gateway

    Browser->>Proxy: 访问受保护资源
    Proxy-->>Browser: 302 /auth/oauth2/login
    Browser->>IdP: Authorization Code + PKCE S256
    IdP-->>Proxy: callback(code, state)
    Proxy->>IdP: code + verifier 换取 Token
    Proxy->>IdP: UserInfo / Introspection(按配置)
    Proxy-->>Browser: HttpOnly 会话 Cookie
    Browser->>Proxy: 再次访问 HTTP / WebSocket
    Proxy->>Proxy: 校验会话、scope、过期与刷新
    Proxy->>Gateway: 覆盖可信身份 Header 后转发
    Gateway-->>Browser: 业务响应

OAuth2 Server 负责登录、授权和 Token 签发;本插件是标准 Client 与授权拦截代理,不实现账号体系,也不充当 OAuth2 Server。

Discovery 配置

{
  "enabled": true,
  "issuerUrl": "https://auth.example.com/",
  "clientId": "openclaw-gateway",
  "clientSecret": "replace-with-secret",
  "client": {
    "discovery": true,
    "redirectUri": "https://gateway.example.com/auth/oauth2/callback",
    "scopes": ["openid", "profile", "openclaw:operator"],
    "requiredScopes": ["openclaw:operator"],
    "clientAuthMethod": "client_secret_post",
    "authorizationParameters": {
      "audience": "openclaw-api",
      "prompt": "login"
    },
    "sessionSecret": "replace-with-at-least-32-random-characters",
    "secureCookies": true,
    "userIdField": "sub",
    "tenantIdField": "tenantId",
    "sessionStore": {
      "type": "redis",
      "redisUrl": "redis://127.0.0.1:6379/0",
      "keyPrefix": "openclaw:oauth2",
      "maxEntries": 10000
    }
  },
  "proxy": {
    "listenHost": "0.0.0.0",
    "listenPort": 18080,
    "upstreamHost": "127.0.0.1",
    "upstreamPort": 18789,
    "forwardedProto": "https"
  }
}

显式端点配置

授权服务没有 Discovery 文档时,将 discovery 设为 false:

{
  "enabled": true,
  "issuerUrl": "https://auth.example.com/",
  "clientId": "openclaw-gateway",
  "clientSecret": "replace-with-secret",
  "client": {
    "discovery": false,
    "redirectUri": "https://gateway.example.com/auth/oauth2/callback",
    "authorizationEndpoint": "https://auth.example.com/oauth2/authorize",
    "tokenEndpoint": "https://auth.example.com/oauth2/token",
    "userInfoEndpoint": "https://auth.example.com/oauth2/userinfo",
    "introspectionEndpoint": "https://auth.example.com/oauth2/introspect",
    "revokeEndpoint": "https://auth.example.com/oauth2/revoke",
    "scopes": ["openid", "profile"],
    "clientAuthMethod": "client_secret_basic",
    "authorizationParameters": {},
    "tokenParameters": {},
    "sessionSecret": "replace-with-at-least-32-random-characters"
  }
}

显式模式至少需要 authorizationEndpoint 与 tokenEndpoint。浏览器登录后的身份可来自 ID Token、UserInfo 或 Introspection;Bearer API 请求需要配置 UserInfo 或 Introspection。

本地端点

| 路径 | 用途 | |---|---| | GET /auth/oauth2/login | 创建 state/PKCE transaction 并跳转授权服务 | | GET /auth/oauth2/callback | 校验 state、交换 token、创建 session | | POST /auth/oauth2/logout | 删除 session 并尝试 revoke access token,避免 GET logout CSRF | | /auth/oauth2/status | 转发给 OpenClaw auth: "gateway" 路由,不在代理层匿名暴露 | | GET/HEAD /health | 代理存活与 OAuth2 Client 就绪检查 |

安全约束

  • OpenClaw 必须保持 loopback 监听,并启用与插件一致的可信代理配置:
{
  "gateway": {
    "port": 18789,
    "bind": "loopback",
    "trustedProxies": ["127.0.0.1"],
    "auth": {
      "mode": "trusted-proxy",
      "trustedProxy": {
        "userHeader": "x-forwarded-user",
        "allowLoopback": true,
        "allowUsers": ["allowed-user-id"]
      }
    }
  }
}
  • 插件启动前会校验 auth.mode、userHeader、allowLoopback、trustedProxies 和 Gateway 端口;不匹配时直接拒绝启动。
  • proxy.upstreamHost 只允许 127.0.0.1 或 ::1,避免成为可访问任意目标的开放代理。
  • 非 loopback 的 issuer 和端点必须使用 HTTPS。
  • 生产环境必须启用 secureCookies。
  • 先验证每个 transaction 的独立签名 Cookie,再一次性消费 state,避免无 Cookie 请求使合法登录失效。
  • 默认禁止 URL query token。
  • 外部请求携带的 forwarded/user/tenant/scope Header 会在代理前删除;只重建可信用户、租户和转发链。
  • OAuth Scope 不会伪装成 OpenClaw operator scope;requiredScopes 只负责代理准入,Gateway 权限由 OpenClaw trusted-proxy 与 allowUsers 配置负责。
  • 内存 session store 有 maxEntries 上限;多实例生产部署应使用 Redis session store。

验证

pnpm --dir extensions/oauth2 test
pnpm --dir extensions/oauth2 typecheck
pnpm --dir extensions/oauth2 build
OPENCLAW_E2E_HOST_GATEWAY=1 node scripts/e2e/run-e2e.mjs --plugins oauth2