Spaces:
Runtime error
Runtime error
feat: default to no-auth mode — Control UI connects instantly
Browse filesUse gateway auth.mode="none" by default so the Control UI auto-connects
without any token. Users who want access control can set GATEWAY_TOKEN
env var to require a token.
Also restore AUTO_CREATE_DATASET check for dataset creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- README.md +3 -3
- openclaw.json +1 -1
- scripts/sync_hf.py +21 -12
README.md
CHANGED
|
@@ -112,7 +112,7 @@ Fine-tune persistence and performance. Set these as **Repository Secrets** in HF
|
|
| 112 |
|
| 113 |
| Variable | Default | Description |
|
| 114 |
|----------|---------|-------------|
|
| 115 |
-
| `GATEWAY_TOKEN` |
|
| 116 |
| `AUTO_CREATE_DATASET` | `false` | **Auto-create the Dataset repo.** Set to `true` to auto-create a private Dataset repo on first startup. |
|
| 117 |
| `SYNC_INTERVAL` | `60` | **Backup interval in seconds.** How often data syncs to the Dataset repo. |
|
| 118 |
|
|
@@ -120,7 +120,7 @@ Fine-tune persistence and performance. Set these as **Repository Secrets** in HF
|
|
| 120 |
|
| 121 |
### 3. Open the Control UI
|
| 122 |
|
| 123 |
-
Visit your Space URL
|
| 124 |
|
| 125 |
Messaging integrations (Telegram, WhatsApp) can be configured directly inside the Control UI after connecting.
|
| 126 |
|
|
@@ -141,7 +141,7 @@ HuggingClaw adds its own variables for persistence and deployment: `HF_TOKEN`, `
|
|
| 141 |
|
| 142 |
## Security
|
| 143 |
|
| 144 |
-
- **
|
| 145 |
- **Secrets stay server-side** — API keys and tokens are never exposed to the browser
|
| 146 |
- **Private backups** — the Dataset repo is created as private by default
|
| 147 |
|
|
|
|
| 112 |
|
| 113 |
| Variable | Default | Description |
|
| 114 |
|----------|---------|-------------|
|
| 115 |
+
| `GATEWAY_TOKEN` | _(none)_ | **Gateway token.** If set, Control UI requires this token to connect. If not set, anyone with the URL can access. |
|
| 116 |
| `AUTO_CREATE_DATASET` | `false` | **Auto-create the Dataset repo.** Set to `true` to auto-create a private Dataset repo on first startup. |
|
| 117 |
| `SYNC_INTERVAL` | `60` | **Backup interval in seconds.** How often data syncs to the Dataset repo. |
|
| 118 |
|
|
|
|
| 120 |
|
| 121 |
### 3. Open the Control UI
|
| 122 |
|
| 123 |
+
Visit your Space URL — the Control UI connects automatically, no token needed. To add access control, set the `GATEWAY_TOKEN` secret.
|
| 124 |
|
| 125 |
Messaging integrations (Telegram, WhatsApp) can be configured directly inside the Control UI after connecting.
|
| 126 |
|
|
|
|
| 141 |
|
| 142 |
## Security
|
| 143 |
|
| 144 |
+
- **Optional token auth** — set `GATEWAY_TOKEN` to restrict Control UI access; without it, the UI is open for easy setup
|
| 145 |
- **Secrets stay server-side** — API keys and tokens are never exposed to the browser
|
| 146 |
- **Private backups** — the Dataset repo is created as private by default
|
| 147 |
|
openclaw.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
"mode": "local",
|
| 4 |
"bind": "lan",
|
| 5 |
"port": 7860,
|
| 6 |
-
"auth": { "
|
| 7 |
"trustedProxies": [
|
| 8 |
"0.0.0.0/0"
|
| 9 |
],
|
|
|
|
| 3 |
"mode": "local",
|
| 4 |
"bind": "lan",
|
| 5 |
"port": 7860,
|
| 6 |
+
"auth": { "mode": "none" },
|
| 7 |
"trustedProxies": [
|
| 8 |
"0.0.0.0/0"
|
| 9 |
],
|
scripts/sync_hf.py
CHANGED
|
@@ -65,8 +65,8 @@ OPENAI_BASE_URL = os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1")
|
|
| 65 |
# OpenRouter API key (optional; alternative to OPENAI_API_KEY + OPENAI_BASE_URL)
|
| 66 |
OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "")
|
| 67 |
|
| 68 |
-
# Gateway token (
|
| 69 |
-
GATEWAY_TOKEN = os.environ.get("GATEWAY_TOKEN", "
|
| 70 |
|
| 71 |
# Default model for new conversations (infer from provider if not set)
|
| 72 |
OPENCLAW_DEFAULT_MODEL = os.environ.get("OPENCLAW_DEFAULT_MODEL") or (
|
|
@@ -172,8 +172,7 @@ class OpenClawFullSync:
|
|
| 172 |
print("[SYNC] WARNING: HF_TOKEN not set. Persistence disabled.")
|
| 173 |
return
|
| 174 |
if not HF_REPO_ID:
|
| 175 |
-
print("[SYNC]
|
| 176 |
-
print("[SYNC] → Set OPENCLAW_DATASET_REPO, or set AUTO_CREATE_DATASET=true to auto-create.")
|
| 177 |
print("[SYNC] Persistence disabled.")
|
| 178 |
return
|
| 179 |
|
|
@@ -184,7 +183,7 @@ class OpenClawFullSync:
|
|
| 184 |
# ── Repo management ────────────────────────────────────────────────
|
| 185 |
|
| 186 |
def _ensure_repo_exists(self):
|
| 187 |
-
"""Check if dataset repo exists; auto-create
|
| 188 |
try:
|
| 189 |
self.api.repo_info(repo_id=HF_REPO_ID, repo_type="dataset")
|
| 190 |
print(f"[SYNC] Dataset repo found: {HF_REPO_ID}")
|
|
@@ -192,10 +191,10 @@ class OpenClawFullSync:
|
|
| 192 |
except Exception:
|
| 193 |
if not AUTO_CREATE_DATASET:
|
| 194 |
print(f"[SYNC] Dataset repo NOT found: {HF_REPO_ID}")
|
| 195 |
-
print(f"[SYNC] AUTO_CREATE_DATASET
|
| 196 |
-
print(f"[SYNC]
|
| 197 |
return False
|
| 198 |
-
print(f"[SYNC] Dataset repo NOT found: {HF_REPO_ID}
|
| 199 |
try:
|
| 200 |
self.api.create_repo(
|
| 201 |
repo_id=HF_REPO_ID,
|
|
@@ -348,9 +347,12 @@ class OpenClawFullSync:
|
|
| 348 |
try:
|
| 349 |
with open(config_path, "r") as f:
|
| 350 |
cfg = json.load(f)
|
| 351 |
-
#
|
| 352 |
if "gateway" in cfg:
|
| 353 |
-
|
|
|
|
|
|
|
|
|
|
| 354 |
if OPENAI_API_KEY and "models" in cfg and "providers" in cfg["models"] and "openai" in cfg["models"]["providers"]:
|
| 355 |
cfg["models"]["providers"]["openai"]["apiKey"] = OPENAI_API_KEY
|
| 356 |
if OPENAI_BASE_URL:
|
|
@@ -429,11 +431,18 @@ class OpenClawFullSync:
|
|
| 429 |
if SPACE_HOST:
|
| 430 |
allowed_origins.append(f"https://{SPACE_HOST}")
|
| 431 |
print(f"[SYNC] SPACE_HOST detected: {SPACE_HOST}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
data["gateway"] = {
|
| 433 |
"mode": "local",
|
| 434 |
"bind": "lan",
|
| 435 |
"port": 7860,
|
| 436 |
-
"auth":
|
| 437 |
"trustedProxies": ["0.0.0.0/0"],
|
| 438 |
"controlUi": {
|
| 439 |
"allowInsecureAuth": True,
|
|
@@ -441,7 +450,7 @@ class OpenClawFullSync:
|
|
| 441 |
"allowedOrigins": allowed_origins
|
| 442 |
}
|
| 443 |
}
|
| 444 |
-
print(f"[SYNC] Set gateway config (auth=
|
| 445 |
|
| 446 |
# Ensure agents defaults
|
| 447 |
data.setdefault("agents", {}).setdefault("defaults", {}).setdefault("model", {})
|
|
|
|
| 65 |
# OpenRouter API key (optional; alternative to OPENAI_API_KEY + OPENAI_BASE_URL)
|
| 66 |
OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "")
|
| 67 |
|
| 68 |
+
# Gateway token (optional; if not set, Control UI connects without auth)
|
| 69 |
+
GATEWAY_TOKEN = os.environ.get("GATEWAY_TOKEN", "")
|
| 70 |
|
| 71 |
# Default model for new conversations (infer from provider if not set)
|
| 72 |
OPENCLAW_DEFAULT_MODEL = os.environ.get("OPENCLAW_DEFAULT_MODEL") or (
|
|
|
|
| 172 |
print("[SYNC] WARNING: HF_TOKEN not set. Persistence disabled.")
|
| 173 |
return
|
| 174 |
if not HF_REPO_ID:
|
| 175 |
+
print("[SYNC] WARNING: Could not determine dataset repo (no SPACE_ID or OPENCLAW_DATASET_REPO).")
|
|
|
|
| 176 |
print("[SYNC] Persistence disabled.")
|
| 177 |
return
|
| 178 |
|
|
|
|
| 183 |
# ── Repo management ────────────────────────────────────────────────
|
| 184 |
|
| 185 |
def _ensure_repo_exists(self):
|
| 186 |
+
"""Check if dataset repo exists; auto-create only when AUTO_CREATE_DATASET=true AND HF_TOKEN is set."""
|
| 187 |
try:
|
| 188 |
self.api.repo_info(repo_id=HF_REPO_ID, repo_type="dataset")
|
| 189 |
print(f"[SYNC] Dataset repo found: {HF_REPO_ID}")
|
|
|
|
| 191 |
except Exception:
|
| 192 |
if not AUTO_CREATE_DATASET:
|
| 193 |
print(f"[SYNC] Dataset repo NOT found: {HF_REPO_ID}")
|
| 194 |
+
print(f"[SYNC] Set AUTO_CREATE_DATASET=true to auto-create.")
|
| 195 |
+
print(f"[SYNC] Persistence disabled (app will still run normally).")
|
| 196 |
return False
|
| 197 |
+
print(f"[SYNC] Dataset repo NOT found: {HF_REPO_ID} — creating...")
|
| 198 |
try:
|
| 199 |
self.api.create_repo(
|
| 200 |
repo_id=HF_REPO_ID,
|
|
|
|
| 347 |
try:
|
| 348 |
with open(config_path, "r") as f:
|
| 349 |
cfg = json.load(f)
|
| 350 |
+
# Set auth based on GATEWAY_TOKEN env var
|
| 351 |
if "gateway" in cfg:
|
| 352 |
+
if GATEWAY_TOKEN:
|
| 353 |
+
cfg["gateway"]["auth"] = {"token": GATEWAY_TOKEN}
|
| 354 |
+
else:
|
| 355 |
+
cfg["gateway"]["auth"] = {"mode": "none"}
|
| 356 |
if OPENAI_API_KEY and "models" in cfg and "providers" in cfg["models"] and "openai" in cfg["models"]["providers"]:
|
| 357 |
cfg["models"]["providers"]["openai"]["apiKey"] = OPENAI_API_KEY
|
| 358 |
if OPENAI_BASE_URL:
|
|
|
|
| 431 |
if SPACE_HOST:
|
| 432 |
allowed_origins.append(f"https://{SPACE_HOST}")
|
| 433 |
print(f"[SYNC] SPACE_HOST detected: {SPACE_HOST}")
|
| 434 |
+
# Auth: token mode if GATEWAY_TOKEN is set, otherwise no-auth mode
|
| 435 |
+
if GATEWAY_TOKEN:
|
| 436 |
+
auth_cfg = {"token": GATEWAY_TOKEN}
|
| 437 |
+
auth_label = f"token"
|
| 438 |
+
else:
|
| 439 |
+
auth_cfg = {"mode": "none"}
|
| 440 |
+
auth_label = "none (open access)"
|
| 441 |
data["gateway"] = {
|
| 442 |
"mode": "local",
|
| 443 |
"bind": "lan",
|
| 444 |
"port": 7860,
|
| 445 |
+
"auth": auth_cfg,
|
| 446 |
"trustedProxies": ["0.0.0.0/0"],
|
| 447 |
"controlUi": {
|
| 448 |
"allowInsecureAuth": True,
|
|
|
|
| 450 |
"allowedOrigins": allowed_origins
|
| 451 |
}
|
| 452 |
}
|
| 453 |
+
print(f"[SYNC] Set gateway config (auth={auth_label}, origins={len(allowed_origins)})")
|
| 454 |
|
| 455 |
# Ensure agents defaults
|
| 456 |
data.setdefault("agents", {}).setdefault("defaults", {}).setdefault("model", {})
|