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

@m1a0rz/agent-identity

v0.4.1

Published

Agent Identity: UserPool (用户池) login, TIP token (工作负载令牌), credential hosting (凭据托管 OAuth2/API key), optional tool/skill permission control (CheckPermission) and risk approval. Integrates with Volcengine 智能体身份和权限管理平台.

Downloads

1,958

Readme

Agent Identity Plugin

UserPool OIDC login, TIP (Trusted Identity Provider) token via Identity GetWorkloadAccessTokenForJWT, credential 3LO (GetResourceOauth2Token/Oauth2Callback), and session management for OpenClaw.

中文文档请参阅 README-cn.md

Integrates with Volcengine Agent Identity and Permission Management.

Features

  • OIDC Login: /identity login returns IdP auth URL (no HTTP start endpoint). User opens URL, IdP redirects to /identity/oauth/callback.
  • TIP Token: before_agent_start hook fetches TIP token when session has a logged-in user.
  • Credential 3LO: /identity fetch <provider> returns auth URL. IdP redirects to Identity-provided callback (control-plane config).
  • Credential Binding: /identity set <provider> <envVar> binds stored credential to env var. Credentials are securely injected per-tool-call, isolated between concurrent multi-user sessions.
  • Encrypted Session Storage: sessions.json is encrypted at rest (AES-256-GCM). Plaintext sessions from older versions are auto-migrated on first load.
  • In-memory TIP Cache: TIP tokens are stored only in memory (no disk persistence). They are short-lived and re-obtained from the user's session token on demand.
  • Dynamic UserPool: Resolve OIDC config by userPoolName + clientName (no manual clientId).
  • Credentials: Load AK/SK from env, file, or STS AssumeRole (veadk-style).

HTTP Endpoints

Only the OIDC login callback is exposed. Credential OAuth uses Identity callback. All other logic runs in slash commands.

| Path | Method | Description | | -------------------------- | ------ | ---------------------------------------- | | /identity/oauth/callback | GET | OIDC login callback (IdP redirects here) |

Slash Commands

Single command /identity (alias /id) with subcommands. Default with no args: status.

| Subcommand | Description | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- | | (none) | Show help. | | whoami | Show current session identity (sub, TIP status). | | login | If logged in: refresh TIP. If not: return OIDC IdP URL to open. | | status | Show login status, TIP, credentials. Tries to refresh TIP when session exists. | | logout | Clear session and TIP for current session. | | list-tips | List all valid TIP tokens with delegation chain, expiry, and env bindings. | | config | Show identity plugin config (sensitive values redacted). | | list-credentials or list [page] | List providers from control plane (paginated) and your credentials with bound env. Use list 2 to load more. | | fetch <provider> [--flow=...] | Add credential. Flow auto-inferred from provider type (api_key/oauth2/m2m); override with --flow. | | set <provider> <envVar> | Bind credential to env var for tool injection. If no credential, import from process.env[envVar]. | | unset <provider> | Remove env binding for provider. | | approve <approval_id> | Approve a pending high-risk tool call. | | reject <approval_id> | Reject a pending high-risk tool call. |

OIDC Login Flow

  1. User sends /identity login in chat (e.g. Telegram, Discord)
  2. Command derives sessionKey from channel/sender, builds IdP authorize URL, stores state
  3. Command returns the IdP URL; user opens it in browser
  4. User completes login at UserPool IdP
  5. IdP redirects to /identity/oauth/callback with code and state
  6. Plugin exchanges code, creates session, shows success page and sends message to chat

Credential Fetch Flow

OAuth2 (user federation or M2M):

  1. User sends /identity fetch google or /identity fetch google --flow=oauth2-m2m (after /identity login)
  2. Command uses TIP to call Identity API; returns auth URL or direct token
  3. If auth URL: user opens it; IdP redirects to Identity callback (control-plane provider config)
  4. Identity handles callback; token obtained via Identity; user may re-run fetch to pull credential

API Key:

  1. User sends /identity fetch openai (provider type api_key in control plane) or /identity fetch openai --flow=apikey
  2. Command uses TIP to call GetResourceApiKey; API key stored directly

Flow is auto-inferred from ListCredentialProviders (Type + Flow). Override with --flow=oauth2-user|oauth2-m2m|apikey when needed.

Enable Volcengine Agent Identity Service

Before using this plugin, you must enable Agent Identity and Permission Management in Volcengine and complete authorization. See:

Get Volcengine AK/SK

The plugin requires Volcengine Access Key and Secret Key to call the Identity API. To create credentials:

After creating AK/SK in the console, pass them via config or use environment variables VOLCENGINE_ACCESS_KEY and VOLCENGINE_SECRET_KEY.

Installation

openclaw plugins install @m1a0rz/agent-identity

Or with link for development:

openclaw plugins install --link .

Configuration

Step 2: Configure plugin (minimal setup)

The plugin typically needs three types of config:

A. Platform access (Identity): For TIP Token, credential fetch/hosting, and optional permission checks.

  • endpoint: Identity API URL (e.g. https://id.cn-beijing.volcengineapi.com). Default when omitted.
  • accessKeyId / secretAccessKey: For Identity API access. Optional when using env vars or credential file (see below).
  • workloadPoolName / workloadName: For issuing TIP Token. Defaults: default, openclaw-agent.
  • audience / durationSeconds: Optional, token audience and validity.
  • credentialsFile: Path to credential JSON. Default: VOLCENGINE_CREDENTIALS_FILE env or /var/run/secrets/iam/credential.
  • credentialsMetadataUrl: Full URL for remote credential fetch. When set with roleTrn, fetches from URL (response: AccessKeyId, SecretAccessKey, SessionToken), then AssumeRole with roleTrn to get final credentials. Same flow as AK/SK + roleTrn. 404 falls through to credential file. Cached by ExpiredTime. Must be explicitly configured.
  • roleTrn: Role TRN for STS AssumeRole. When set (and workloadName not set), workload name is omitted; backend uses roleName. Priority: workloadName > roleTrn > params. Used with credentialsMetadataUrl (AssumeRole after fetch) or explicit AK/SK.
  • sessionToken: STS session token (or use VOLCENGINE_SESSION_TOKEN env).

Credential resolution order (AK/SK): 1) Explicit config → 2) Env vars (VOLCENGINE_ACCESS_KEY, VOLCENGINE_SECRET_KEY, VOLCENGINE_SESSION_TOKEN) → 3) Remote metadata (credentialsMetadataUrl + roleTrn, fetches from full URL then AssumeRole; 404 falls through) → 4) Credential file (credentialsFile config, or VOLCENGINE_CREDENTIALS_FILE env, or /var/run/secrets/iam/credential). Credential file format (VeFaaS): access_key_id, secret_access_key, session_token (optional), role_trn (optional for AssumeRole). RUNTIME_IAM_ROLE_TRN env can supply role TRN when loading from file.

B. User login (UserPool / OIDC): For /identity login and session setup.

  • discoveryUrl (or userPoolName + clientName for dynamic resolution)
  • clientId / clientSecret (auto-resolved in dynamic mode)
  • callbackUrl: Public callback URL for OpenClaw gateway, e.g. http://127.0.0.1:18789/identity/oauth/callback
  • scope: Typically openid profile email

C. AuthZ and risk approval (optional): For TIP + CheckPermission + risk evaluation. Each flag is independent; no single "enable" switch.

  • agentCheck: Run CheckPermission for agents (resource type agent) in before_agent_start. Verifies the user can invoke the current agent. Uses the outermost actor from TIP delegation chain as resource id. Default false.
  • toolCheck: Run CheckPermission for tools (resource type tool). Default false.
  • skillReadCheck: Run CheckPermission for read of SKILL.md (resource type skill). Parses available_skills from system prompt. Default false.
  • requireRiskApproval: Require user approval for high-risk tool calls. Default false.
  • namespaceName: CheckPermission Cedar policy namespace. Default default.
  • lowRiskBypass: Skip TIP+CheckPermission for built-in low-risk tools. Default true.
  • lowRiskTools: Extra tool names treated as low-risk.
  • enableLlmRiskCheck: Use LLM to re-evaluate when rules return medium. Default false.
  • llmRiskCheck: LLM config (endpoint, api, model, apiKey, timeoutMs, cacheTtlMs). Required when enableLlmRiskCheck is true.
  • approvalTtlSeconds: Approval link/command TTL (seconds). Default 300.

Expected outcome: After config, the plugin can initiate login and obtain TIP Token. With AuthZ flags enabled, agent/tool/skill permission checks and high-risk approvals apply; use /identity approve <approval_id> to approve blocked calls.


Add to openclaw.json under plugins.entries.agent-identity.config:

{
  "plugins": {
    "entries": {
      "agent-identity": {
        "config": {
          "identity": {
            "endpoint": "https://id.cn-beijing.volcengineapi.com",
            "workloadPoolName": "default",
            "workloadName": "openclaw-agent"
          },
          "userpool": {
            "discoveryUrl": "https://userpool-xxx.userpool.auth.id.cn-beijing.volces.com",
            "clientId": "<client-id>",
            "clientSecret": "<client-secret>",
            "callbackUrl": "https://gateway.example.com/identity/oauth/callback",
            "scope": "openid profile email"
          },
          "authz": {
            "agentCheck": false,
            "toolCheck": false,
            "skillReadCheck": false,
            "requireRiskApproval": false,
            "namespaceName": "default",
            "lowRiskBypass": true,
            "enableLlmRiskCheck": false,
            "approvalTtlSeconds": 300
          }
        }
      }
    }
  }
}

Identity credentials: Omit accessKeyId/secretAccessKey to use env vars (VOLCENGINE_ACCESS_KEY, VOLCENGINE_SECRET_KEY) or credential file (VOLCENGINE_CREDENTIALS_FILE or /var/run/secrets/iam/credential).

identity config (required vs optional)

| Param | Type | Required | Description | |-------|------|----------|--------------| | endpoint | string | Yes | Identity API URL, e.g. https://id.cn-beijing.volcengineapi.com | | accessKeyId | string | No* | Volcengine Access Key. Omit to load from VOLCENGINE_ACCESS_KEY or credentialsFile | | secretAccessKey | string | No* | Volcengine Secret Key. Omit to load from VOLCENGINE_SECRET_KEY or credentialsFile | | workloadPoolName | string | No | Workload pool name, default default | | workloadName | string | No | Workload name for TIP. When set, takes precedence over roleTrn. Default when neither set: agentId or openclaw-agent | | audience | string[] | No | TIP token audience | | durationSeconds | number | No | TIP token TTL (seconds), default 3600 | | roleTrn | string | No | Role TRN for STS AssumeRole. When set (and workloadName not set), workload name is omitted; backend uses roleName. Priority: workloadName > roleTrn > params | | credentialsFile | string | No | Path to credential JSON. Default: VOLCENGINE_CREDENTIALS_FILE or /var/run/secrets/iam/credential | | credentialsMetadataUrl | string | No | Full URL for remote credential fetch. When set with roleTrn, fetches then AssumeRole. 404 falls through to credentialsFile | | sessionToken | string | No | STS session token (or VOLCENGINE_SESSION_TOKEN) | | subagentTipPropagation | boolean | No | Propagate TIP and session to subagents. Default false | | webchatSessionExchange | boolean | No | Enable identity.session.put / identity.session.get gateway WS methods for webchat clients. Default false |

* AK/SK must be provided via accessKeyId+secretAccessKey, environment variables, credentialsMetadataUrl+roleTrn, or credentialsFile.

Environment variables: VOLCENGINE_ACCESS_KEY, VOLCENGINE_SECRET_KEY, VOLCENGINE_SESSION_TOKEN, VOLCENGINE_CREDENTIALS_FILE, RUNTIME_IAM_ROLE_TRN (for AssumeRole when loading from file). Set IDENTITY_STS_DEBUG=1 to log full STS AssumeRole request/response for debugging.

userpool config (OIDC login)

Explicit mode (required): discoveryUrl, clientId, clientSecret, callbackUrl, scope

Dynamic mode (required): userPoolName, clientName, callbackUrl; autoCreate defaults to true

OAuth2 credential fetch uses control-plane redirect URL and scopes. Override via /identity fetch <provider> --redirectUrl and --scopes.

authz config (optional, each flag independent)

| Param | Type | Description | |-------|------|-------------| | agentCheck | boolean | Run CheckPermission for agents (resource type agent) in before_agent_start. Verifies the user can invoke the current agent. Uses the outermost actor from TIP delegation chain as resource id. Default false. | | toolCheck | boolean | Run CheckPermission for tools (resource type tool). Default false. | | skillReadCheck | boolean | Run CheckPermission for read of SKILL.md (resource type skill). Default false. | | requireRiskApproval | boolean | Require user approval for high-risk tools. Default false. | | namespaceName | string | CheckPermission Cedar namespace. Default default. | | lowRiskBypass | boolean | Skip TIP+CheckPermission for built-in low-risk tools. Default true. | | lowRiskTools | string[] | Extra tool names treated as low-risk. | | enableLlmRiskCheck | boolean | Re-evaluate with LLM when rules return medium. Default false. | | llmRiskCheck | object | LLM config: endpoint, api, model, etc. Required when enableLlmRiskCheck is true. | | approvalTtlSeconds | number | Approval TTL (seconds). Default 300. |

Workload and TIP

TIP token is obtained via GetWorkloadAccessTokenForJWT. Workload behavior:

  • workloadName (optional): Workload name sent to the API. Priority: config.workloadName > config.roleTrn > params (session agentId or "openclaw-agent"). When config.workloadName is set, it takes precedence over roleTrn.
  • roleTrn (optional): When set (and workloadName not set), the plugin does not pass workload name; the backend uses the role name. Use this for delegated execution (e.g. VeFaaS, K8s IRSA).
  • Auto-create workload: When GetWorkloadAccessTokenForJWT returns 404 (workload not found), the plugin calls CreateWorkloadIdentity to create the workload (Category: Agent), then retries. Only applies when a workload name is used (workloadName set or neither workloadName nor roleTrn set). Duplicated (409) from concurrent create is ignored.

Feishu notifications

Login success and credential fetch follow-up messages (e.g. "✓ Credential for google added.") are sent via Feishu when the user runs /identity from a Feishu chat. Credentials are read from channels.feishu in openclaw.json (same as feishu extension: appId, appSecret, optional accounts). No extra config in agent-identity is required.

Approval messages (when a high-risk tool is blocked): For approval requests to be delivered to Feishu (or Telegram, Slack, etc.), set session.dmScope to per-channel-peer or per-account-channel-peer in openclaw.json. With default session.dmScope: "main", the sessionKey does not include channel/peer info, so the plugin cannot derive a delivery target and approval messages are not pushed. The user will still see the block/approval_id in the agent's error reply; use /identity approve <id> to approve.

WebChat Session Exchange (Gateway WS Methods)

When identity.webchatSessionExchange is true, the plugin registers two gateway WebSocket methods for webchat clients to inject and retrieve session tokens without going through the OIDC redirect flow:

| Method | Params | Response | Description | | --- | --- | --- | --- | | identity.session.put | { sessionKey, idToken, senderId?, channel? } | { sub, expiresAt, effectiveSessionKey, hasTip } | Inject an OIDC id_token into a plugin session. Resolves effective storage key via buildEffectiveSessionKey (same sender isolation as hooks/commands). | | identity.session.get | { sessionKey, senderId?, channel? } | { userToken, sub, expiresAt, effectiveSessionKey } | Retrieve the stored user token for a session. |

  • senderId defaults to "openclaw-control-ui". The effective storage key is agent:main:main:user:<senderId> for main sessions.
  • channel is optional; when the session originates from a sendable channel (feishu, telegram, etc.), pass it to enable per-channel-peer key promotion.

Both methods are restricted to webchat WS connections only (isWebchatConnect check). Non-webchat clients receive a FORBIDDEN error.

Config:

{
  "identity": {
    "webchatSessionExchange": true
  }
}

Typical flow (BFF → webchat → plugin):

  1. BFF completes 3LO login and obtains an OIDC id_token for the user
  2. Webchat client calls identity.session.put with the session key and id_token
  3. Plugin verifies the token, stores the session, and acquires TIP
  4. Subsequent agent runs in that session have a valid identity — no manual login needed

WebChat / TUI

Follow-up messages (login success, credential fetch done) are not delivered when the user runs /identity from WebChat or TUI; the plugin has no API to push to those channels. Use /identity status to confirm results.

Tools

  • identity_whoami - Show current session identity (sub, TIP status)
  • identity_status - Login status, credentials, bindings
  • identity_login - Start OIDC login or refresh TIP
  • identity_logout - Clear session and TIP
  • identity_list_credentials - List providers and credentials (paginated)
  • identity_list_tips - List valid TIP tokens and bindings
  • identity_config - Show plugin config (redacted)
  • identity_config_suggest - Generate config snippets for openclaw.json (intent, lang)
  • identity_fetch - Add credential (provider, flow?, redirectUrl?, scopes?)
  • identity_set_binding - Bind provider → env var
  • identity_unset_binding - Remove env binding
  • identity_approve_tool - Optional tool; approve high-risk tool call by approval_id. Prefer /identity approve <id> (human-only; agent must not self-approve).
  • identity_risk_check - Diagnose risk for a command or tool call (command, or toolName+params)
  • identity_list_risk_patterns - List built-in dangerous commands and sensitive paths

Hooks

  • before_agent_start - Fetch TIP token for main agent only. When authz.agentCheck is enabled, runs CheckPermission to verify the user can invoke the agent.
  • subagent_spawned - Propagate TIP to child session on subagent spawn.
  • before_tool_call - Group context injection, optional AuthZ (TIP check, CheckPermission, risk approval), and per-tool-call credential injection.
  • after_tool_call - Clean up per-tool-call credential injection state.

Data Storage

Plugin data at ~/.openclaw/plugins/identity/:

| File | Description | |------|-------------| | sessions.json | Encrypted sessionKey → userToken mapping. Expired entries pruned on load/save. | | credential-env-bindings.json | Per-session: { [sessionKey]: { [provider]: envVar } } |

In-memory only (not persisted to disk):

| Data | Description | |------|-------------| | TIP tokens | sessionKey → TIP token cache. Short-lived, re-obtained from session token on demand. | | Credentials | Per-session (api_key, oauth2). Lost on gateway restart; cleared on logout. | | OIDC state | Ephemeral, 5 min TTL. |