mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
feat(ocp-connect): auto-discover anonymous key from /health (v1.3.0) (#16)
Closes the zero-config loop opened by #15 (server anonymous allowlist). ## Why After #15 (v3.7.0) the OCP server exposes the admin-chosen anonymous key via `GET /health.anonymousKey` whenever `PROXY_ANONYMOUS_KEY` is set. Before this PR, users still had to copy that key manually and pass it as `--key` every time they ran `ocp-connect`. This commit closes the last mile: `ocp-connect <host>` now reads the key from the server and uses it automatically when no `--key` was provided. Result: `ocp-connect 172.16.2.30` (zero args) on a fresh machine configures OpenClaw multi-agent correctly against a v3.7.0 OCP instance that has `PROXY_ANONYMOUS_KEY` set. No admin coordination, no per-user keys, no manual flags. ## What changes `OCP_CONNECT_VERSION` 1.2.0 to 1.3.0. New Step 2.5 between the existing Step 2 (Show remote info) and Step 3 (Determine if key is needed). The block: 1. Short-circuits if `--key` was passed explicitly, so user intent always wins over auto-discovery. 2. Parses `health_json.anonymousKey` via python3 with try/except, defensively treating any parse error as "no anon key" so the script falls through to the existing Step 3 path. 3. If the server advertised a non-empty anon key, assigns it to the internal `key` variable and prints an info banner with the truncated key value and a reference to issue #12 section 14 Path A so users can understand what happened. All downstream code (key verification via /v1/models, rc file exports, launchctl setenv, OpenClaw agentDir profile seeding, smoke test, IDE hints) works unchanged because it reads the same `key` variable. Also: defensive check on `--key` to reject explicit empty values (`--key ""`) with a clear error message. Existing bash `${2:?msg}` expansion already rejects empty strings, but the new check is an extra safety net and gives a friendlier error (`omit --key entirely for anonymous mode`). ## Backward compatibility Old OCP servers (less than 3.7.0) that don't have the `anonymousKey` field in `/health`: `python3 d.get("anonymousKey")` returns None, new block outputs empty string, `[[ -n "" ]]` is false, block falls through to the existing Step 3 path. Script behavior is 100% identical to v1.2.0 for these users. New OCP servers that haven't set `PROXY_ANONYMOUS_KEY`: field is null, same fall-through path as above. No user-visible regression in either case. No new CLI flag, no new prompt, no new error path for existing users. ## Test evidence Live offline test on macOS 13 against real 172.16.2.30 (OCP v3.7.0 with `PROXY_ANONYMOUS_KEY=ocp_public_anon_v1`): Step 1: cold install state - stopped OpenClaw gateway - rm ~/.openclaw/agents/{main,macbook_bot}/agent/auth-profiles.json - stripped models.* and agents.defaults.{model,models} from openclaw.json - cleaned OCP LAN block from .bashrc - unset OPENAI_BASE_URL and OPENAI_API_KEY from launchctl env Step 2: ran ~/projects/ocp/ocp-connect 172.16.2.30 (no args) Output: OCP Connect v1.3.0 Remote OCP v3.7.0 (auth: multi) Using server-advertised anonymous key: ocp_publ...n_v1 (set by admin via PROXY_ANONYMOUS_KEY; see issue #12 section 14 Path A) API accessible (3 models available) Per-agent auth profile seeded (2): - ~/.openclaw/agents/main/agent/auth-profiles.json - ~/.openclaw/agents/macbook_bot/agent/auth-profiles.json Smoke test passed: OK EXIT 0 Step 3: verified profiles contain the anon key macbook_bot: key = ocp_public_anon_v1 main: key = ocp_public_anon_v1 Additional regression tests: - ocp-connect 172.16.2.30 --key ocp_real_admin_key -> still uses the explicit key, auto-discovery banner NOT shown - ocp-connect --version -> "ocp-connect 1.3.0" - ocp-connect 172.16.2.30 --key "" -> rejected with clear error ## Code review One independent opus reviewer. Verdict PASS WITH CONCERNS, 0 blockers. Reviewer's Concern B (--key "" edge case) turned out to be a false alarm on my side verification: bash `${2:?}` expansion already rejects empty strings. I added an extra defensive check anyway for clearer error message and safety if the arg parser is refactored in the future. Other concerns (nice-to-have simplifications like `print(k or '')`) are cosmetic and deferred. Co-authored-by: taodeng <taodeng@Taos-MBP> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
taodeng
Claude Opus 4.6
parent
38070fbabb
commit
d71e0455e3
+31
-2
@@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
OCP_CONNECT_VERSION="1.2.0"
|
OCP_CONNECT_VERSION="1.3.0"
|
||||||
|
|
||||||
show_version() {
|
show_version() {
|
||||||
echo "ocp-connect $OCP_CONNECT_VERSION"
|
echo "ocp-connect $OCP_CONNECT_VERSION"
|
||||||
@@ -449,7 +449,9 @@ main() {
|
|||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--port) port="${2:?'--port requires a value'}"; shift 2 ;;
|
--port) port="${2:?'--port requires a value'}"; shift 2 ;;
|
||||||
--key) key="${2:?'--key requires a value'}"; shift 2 ;;
|
--key) key="${2:?'--key requires a value'}"
|
||||||
|
[[ -z "$key" ]] && { echo "Error: --key cannot be empty (omit --key entirely for anonymous mode)"; exit 1; }
|
||||||
|
shift 2 ;;
|
||||||
--version) show_version; exit 0 ;;
|
--version) show_version; exit 0 ;;
|
||||||
--help|-h) show_help; exit 0 ;;
|
--help|-h) show_help; exit 0 ;;
|
||||||
-*) echo "Unknown option: $1"; show_help; exit 1 ;;
|
-*) echo "Unknown option: $1"; show_help; exit 1 ;;
|
||||||
@@ -503,6 +505,33 @@ main() {
|
|||||||
echo " Remote OCP v$remote_version (auth: $auth_mode)"
|
echo " Remote OCP v$remote_version (auth: $auth_mode)"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Step 2.5: auto-discover anonymous key from /health (issue #12 §14 Path A).
|
||||||
|
# When the OCP admin set PROXY_ANONYMOUS_KEY, the server advertises it via
|
||||||
|
# /health.anonymousKey. If the user didn't pass --key, use it automatically so
|
||||||
|
# `ocp-connect <host>` works zero-config for OpenClaw multi-agent setups.
|
||||||
|
if [[ -z "$key" ]]; then
|
||||||
|
local anon_key
|
||||||
|
anon_key=$(echo "$health_json" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
try:
|
||||||
|
d = json.loads(sys.stdin.read())
|
||||||
|
k = d.get('anonymousKey')
|
||||||
|
except Exception:
|
||||||
|
k = None
|
||||||
|
print(k if k else '')
|
||||||
|
" 2>/dev/null || echo "")
|
||||||
|
if [[ -n "$anon_key" ]]; then
|
||||||
|
key="$anon_key"
|
||||||
|
local _anon_display="$anon_key"
|
||||||
|
if [[ ${#anon_key} -gt 16 ]]; then
|
||||||
|
_anon_display="${anon_key:0:8}...${anon_key: -4}"
|
||||||
|
fi
|
||||||
|
echo " ⓘ Using server-advertised anonymous key: $_anon_display"
|
||||||
|
echo " (set by admin via PROXY_ANONYMOUS_KEY; see issue #12 §14 Path A)"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Step 3: Determine if key is needed
|
# Step 3: Determine if key is needed
|
||||||
if [[ "$auth_mode" != "none" && -z "$key" ]]; then
|
if [[ "$auth_mode" != "none" && -z "$key" ]]; then
|
||||||
# Try anonymous access first (zero-config: server may allow it)
|
# Try anonymous access first (zero-config: server may allow it)
|
||||||
|
|||||||
Reference in New Issue
Block a user