openclaw - 💡(How to fix) Fix Feature: Dynamic identity resolution for allowlists (dmPolicy: dynamic) [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#58057Fetched 2026-04-08 01:54:26
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Root Cause

  • Multi-user deployments (SaaS-style) cannot edit config per user
  • iMessage identifiers are unpredictable (phone vs Apple ID email) — can't pre-populate
  • The identity data already exists in databases (e.g., Supabase user_identifiers) — duplicating it into static JSON is tech debt
  • WhatsApp/Telegram handle routing dynamically; BlueBubbles/iMessage should too
  • The allowlist check at step 3 happens BEFORE hooks fire at step 4, so existing hooks can't work around this

Fix Action

Fix / Workaround

Workaround (current)

Manual script that edits openclaw.json + sends SIGUSR1. Works but is operational overhead that grows linearly with users.

Code Example

{
  "dmPolicy": "dynamic",
  "dmResolver": {
    "url": "http://localhost:3456/internal/user/resolve",
    "params": { "channel": "{{channel}}", "address": "{{sender}}" },
    "cacheTtlSeconds": 300
  }
}

---

{
  "dmPolicy": "dynamic",
  "unknownSenderAgent": "onboarding"
}
RAW_BUFFERClick to expand / collapse

Problem

The current dmPolicy: "allowlist" and groupPolicy: "allowlist" require hardcoded sender identifiers in openclaw.json. Every new user requires a config edit + gateway reload. This does not scale for multi-user deployments, especially on channels like BlueBubbles/iMessage where identifiers can be phone numbers OR Apple ID emails.

Current Flow (broken for scale)

  1. New user messages bot
  2. Gateway checks allowFrom array in static config
  3. Sender not found → message silently dropped
  4. Admin must: SSH in, edit openclaw.json, add identifier, reload gateway

Proposed Solution

dmPolicy: "dynamic" / groupPolicy: "dynamic"

Instead of checking a static array, the gateway resolves identity dynamically at request time.

Option A — HTTP resolver:

{
  "dmPolicy": "dynamic",
  "dmResolver": {
    "url": "http://localhost:3456/internal/user/resolve",
    "params": { "channel": "{{channel}}", "address": "{{sender}}" },
    "cacheTtlSeconds": 300
  }
}

Gateway calls the URL with sender info. If 200 + user found → allow. If 404 → deny (or route to unknown-sender handler).

Option B — Authorization hook: A new hook event message:authorize that fires BEFORE the allowlist check. Hook returns { "allow": true/false }. This lets custom logic decide (e.g., query a database).

Unknown Sender Handler

When a sender is denied, instead of silently dropping, optionally route to a designated agent/session for self-service identity linking:

{
  "dmPolicy": "dynamic",
  "unknownSenderAgent": "onboarding"
}

Dynamic Group Policy

Similarly, groupPolicy: "dynamic" would check if a session binding exists for the group instead of requiring a static groups dict entry. If a binding exists → group is allowed.

Why This Matters

  • Multi-user deployments (SaaS-style) cannot edit config per user
  • iMessage identifiers are unpredictable (phone vs Apple ID email) — can't pre-populate
  • The identity data already exists in databases (e.g., Supabase user_identifiers) — duplicating it into static JSON is tech debt
  • WhatsApp/Telegram handle routing dynamically; BlueBubbles/iMessage should too
  • The allowlist check at step 3 happens BEFORE hooks fire at step 4, so existing hooks can't work around this

Workaround (current)

Manual script that edits openclaw.json + sends SIGUSR1. Works but is operational overhead that grows linearly with users.

Environment

  • OpenClaw gateway on macOS (Mac Mini M4)
  • BlueBubbles channel
  • Identity data in Supabase user_identifiers table

extent analysis

Fix Plan

To implement a scalable solution, we will use the proposed dmPolicy: "dynamic" with an HTTP resolver. We will create an API endpoint to resolve user identities dynamically.

Step 1: Create an API Endpoint

Create a new API endpoint http://localhost:3456/internal/user/resolve that takes channel and address as parameters. This endpoint will query the Supabase user_identifiers table to check if the sender is a known user.

Step 2: Implement the API Endpoint

from fastapi import FastAPI, HTTPException
from supabase import create_client, Client

app = FastAPI()
supabase_url: str = "https://your-supabase-url.supabase.co"
supabase_key: str = "your-supabase-key"
supabase: Client = create_client(supabase_url, supabase_key)

@app.get("/internal/user/resolve")
async def resolve_user(channel: str, address: str):
    data = supabase.from_("user_identifiers").select("*").eq("channel", channel).eq("address", address).execute()
    if data.data:
        return {"user_found": True}
    else:
        raise HTTPException(status_code=404, detail="User not found")

Step 3: Configure OpenClaw

Update the openclaw.json configuration to use the dynamic policy with the new API endpoint:

{
  "dmPolicy": "dynamic",
  "dmResolver": {
    "url": "http://localhost:3456/internal/user/resolve",
    "params": { "channel": "{{channel}}", "address": "{{sender}}" },
    "cacheTtlSeconds": 300
  }
}

Step 4: Handle Unknown Senders

Optionally, configure an unknown sender handler to route denied senders to a designated agent/session for self-service identity linking:

{
  "dmPolicy": "dynamic",
  "unknownSenderAgent": "onboarding"
}

Verification

To verify that the fix worked, test the API endpoint with a known and unknown user. Then, send a message from a new user and check if the message is allowed or denied accordingly.

Extra Tips

  • Make sure to replace the supabase_url and supabase_key placeholders with your actual Supabase credentials.
  • Consider implementing authentication and authorization for the API endpoint to prevent unauthorized access.
  • You can also use the Authorization hook option instead of the HTTP resolver, depending on your specific requirements.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING