openclaw-gateway: document and surface pairing-mode requirements
This commit is contained in:
@@ -29,12 +29,15 @@ Open the printed `Dashboard URL` (includes `#token=...`) in your browser.
|
|||||||
- Confirm the created agent uses `openclaw_gateway` (not `openclaw`).
|
- Confirm the created agent uses `openclaw_gateway` (not `openclaw`).
|
||||||
- Confirm gateway URL is `ws://...` or `wss://...`.
|
- Confirm gateway URL is `ws://...` or `wss://...`.
|
||||||
- Confirm gateway token is non-trivial (not empty / not 1-char placeholder).
|
- Confirm gateway token is non-trivial (not empty / not 1-char placeholder).
|
||||||
|
- Confirm pairing mode is explicit:
|
||||||
|
- smoke/dev default: set `adapterConfig.disableDeviceAuth=true` to avoid interactive pairing prompts on each run
|
||||||
|
- if keeping device auth enabled: set a stable `adapterConfig.devicePrivateKeyPem` so pairing is approved once and reused
|
||||||
- If you can run API checks with board auth:
|
- If you can run API checks with board auth:
|
||||||
```bash
|
```bash
|
||||||
AGENT_ID="<newly-created-agent-id>"
|
AGENT_ID="<newly-created-agent-id>"
|
||||||
curl -sS -H "Cookie: $PAPERCLIP_COOKIE" "http://127.0.0.1:3100/api/agents/$AGENT_ID" | jq '{adapterType,adapterConfig:{url:.adapterConfig.url,tokenLen:(.adapterConfig.headers["x-openclaw-token"] // .adapterConfig.headers["x-openclaw-auth"] // "" | length)}}'
|
curl -sS -H "Cookie: $PAPERCLIP_COOKIE" "http://127.0.0.1:3100/api/agents/$AGENT_ID" | jq '{adapterType,adapterConfig:{url:.adapterConfig.url,tokenLen:(.adapterConfig.headers["x-openclaw-token"] // .adapterConfig.headers["x-openclaw-auth"] // "" | length),disableDeviceAuth:(.adapterConfig.disableDeviceAuth // false),hasDeviceKey:(.adapterConfig.devicePrivateKeyPem // "" | length > 0)}}'
|
||||||
```
|
```
|
||||||
- Expected: `adapterType=openclaw_gateway` and `tokenLen >= 16`.
|
- Expected: `adapterType=openclaw_gateway`, `tokenLen >= 16`, and (`disableDeviceAuth=true` OR `hasDeviceKey=true`).
|
||||||
|
|
||||||
7. Case A (manual issue test).
|
7. Case A (manual issue test).
|
||||||
- Create an issue assigned to the OpenClaw agent.
|
- Create an issue assigned to the OpenClaw agent.
|
||||||
@@ -60,6 +63,7 @@ docker compose -f /tmp/openclaw-docker/docker-compose.yml -f /tmp/openclaw-docke
|
|||||||
|
|
||||||
11. Expected pass criteria.
|
11. Expected pass criteria.
|
||||||
- Preflight: `openclaw_gateway` + non-placeholder token (`tokenLen >= 16`).
|
- Preflight: `openclaw_gateway` + non-placeholder token (`tokenLen >= 16`).
|
||||||
|
- Pairing mode: either `disableDeviceAuth=true` (smoke/dev) or stable `devicePrivateKeyPem` configured.
|
||||||
- Case A: `done` + marker comment.
|
- Case A: `done` + marker comment.
|
||||||
- Case B: `done` + marker comment + main-chat message visible.
|
- Case B: `done` + marker comment + main-chat message visible.
|
||||||
- Case C: original task done and new issue created from `/new` session.
|
- Case C: original task done and new issue created from `/new` session.
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ POST /api/companies/$CLA_COMPANY_ID/invites
|
|||||||
"headers": { "x-openclaw-token": "<gateway-token>" },
|
"headers": { "x-openclaw-token": "<gateway-token>" },
|
||||||
"role": "operator",
|
"role": "operator",
|
||||||
"scopes": ["operator.admin"],
|
"scopes": ["operator.admin"],
|
||||||
|
"disableDeviceAuth": true,
|
||||||
"sessionKeyStrategy": "fixed",
|
"sessionKeyStrategy": "fixed",
|
||||||
"sessionKey": "paperclip",
|
"sessionKey": "paperclip",
|
||||||
"waitTimeoutMs": 120000
|
"waitTimeoutMs": 120000
|
||||||
@@ -263,6 +264,9 @@ POST /api/companies/$CLA_COMPANY_ID/invites
|
|||||||
- `adapterConfig.url` uses `ws://` or `wss://`
|
- `adapterConfig.url` uses `ws://` or `wss://`
|
||||||
- `adapterConfig.headers.x-openclaw-token` exists and is not placeholder/too-short (`len >= 16`)
|
- `adapterConfig.headers.x-openclaw-token` exists and is not placeholder/too-short (`len >= 16`)
|
||||||
- token hash matches the OpenClaw `gateway.auth.token` used for join
|
- token hash matches the OpenClaw `gateway.auth.token` used for join
|
||||||
|
- pairing mode is explicit:
|
||||||
|
- smoke/dev: `adapterConfig.disableDeviceAuth == true` (no interactive pairing gate)
|
||||||
|
- otherwise: stable `adapterConfig.devicePrivateKeyPem` is set so approvals persist across runs
|
||||||
5. Claim API key with `claimSecret`.
|
5. Claim API key with `claimSecret`.
|
||||||
6. Save claimed token to OpenClaw expected file path (`~/.openclaw/workspace/paperclip-claimed-api-key.json`) and ensure `PAPERCLIP_API_KEY` + `PAPERCLIP_API_URL` are available for OpenClaw skill execution context.
|
6. Save claimed token to OpenClaw expected file path (`~/.openclaw/workspace/paperclip-claimed-api-key.json`) and ensure `PAPERCLIP_API_KEY` + `PAPERCLIP_API_URL` are available for OpenClaw skill execution context.
|
||||||
- Write compatibility JSON keys (`token` and `apiKey`) to avoid runtime parser mismatch.
|
- Write compatibility JSON keys (`token` and `apiKey`) to avoid runtime parser mismatch.
|
||||||
@@ -318,6 +322,7 @@ Responsibilities:
|
|||||||
- Old OpenClaw agent cleanup.
|
- Old OpenClaw agent cleanup.
|
||||||
- Invite/join/approve/claim orchestration.
|
- Invite/join/approve/claim orchestration.
|
||||||
- Gateway agent config/token preflight validation before connectivity or case execution.
|
- Gateway agent config/token preflight validation before connectivity or case execution.
|
||||||
|
- Pairing-mode preflight (`disableDeviceAuth=true` for smoke/dev or stable `devicePrivateKeyPem`).
|
||||||
- E2E case execution + assertions.
|
- E2E case execution + assertions.
|
||||||
- Final summary with run IDs, issue IDs, agent ID.
|
- Final summary with run IDs, issue IDs, agent ID.
|
||||||
|
|
||||||
|
|||||||
@@ -1074,15 +1074,23 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
|||||||
const message = err instanceof Error ? err.message : String(err);
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
const lower = message.toLowerCase();
|
const lower = message.toLowerCase();
|
||||||
const timedOut = lower.includes("timeout");
|
const timedOut = lower.includes("timeout");
|
||||||
|
const pairingRequired = lower.includes("pairing required");
|
||||||
|
const detailedMessage = pairingRequired
|
||||||
|
? `${message}. Configure adapterConfig.disableDeviceAuth=true for smoke/dev, or set adapterConfig.devicePrivateKeyPem so pairing persists across runs.`
|
||||||
|
: message;
|
||||||
|
|
||||||
await ctx.onLog("stderr", `[openclaw-gateway] request failed: ${message}\n`);
|
await ctx.onLog("stderr", `[openclaw-gateway] request failed: ${detailedMessage}\n`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
signal: null,
|
signal: null,
|
||||||
timedOut,
|
timedOut,
|
||||||
errorMessage: message,
|
errorMessage: detailedMessage,
|
||||||
errorCode: timedOut ? "openclaw_gateway_timeout" : "openclaw_gateway_request_failed",
|
errorCode: timedOut
|
||||||
|
? "openclaw_gateway_timeout"
|
||||||
|
: pairingRequired
|
||||||
|
? "openclaw_gateway_pairing_required"
|
||||||
|
: "openclaw_gateway_request_failed",
|
||||||
resultJson: asRecord(latestResultPayload),
|
resultJson: asRecord(latestResultPayload),
|
||||||
};
|
};
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1430,6 +1430,7 @@ export function buildInviteOnboardingTextDocument(
|
|||||||
waitTimeoutMs: 120000,
|
waitTimeoutMs: 120000,
|
||||||
sessionKeyStrategy: "fixed",
|
sessionKeyStrategy: "fixed",
|
||||||
sessionKey: "paperclip",
|
sessionKey: "paperclip",
|
||||||
|
disableDeviceAuth: true,
|
||||||
role: "operator",
|
role: "operator",
|
||||||
scopes: ["operator.admin"]
|
scopes: ["operator.admin"]
|
||||||
}
|
}
|
||||||
@@ -1445,6 +1446,9 @@ export function buildInviteOnboardingTextDocument(
|
|||||||
IMPORTANT: You MUST include agentDefaultsPayload.headers.x-openclaw-token with your gateway token.
|
IMPORTANT: You MUST include agentDefaultsPayload.headers.x-openclaw-token with your gateway token.
|
||||||
Legacy x-openclaw-auth is also accepted, but x-openclaw-token is preferred.
|
Legacy x-openclaw-auth is also accepted, but x-openclaw-token is preferred.
|
||||||
Use adapterType "openclaw_gateway" and a ws:// or wss:// gateway URL.
|
Use adapterType "openclaw_gateway" and a ws:// or wss:// gateway URL.
|
||||||
|
Pairing mode requirement:
|
||||||
|
- For smoke/dev, set "disableDeviceAuth": true to avoid interactive pairing blocks.
|
||||||
|
- If device auth remains enabled, set a stable "devicePrivateKeyPem"; otherwise each run may generate a new device identity and trigger pairing again.
|
||||||
Do NOT use /v1/responses or /hooks/* in this gateway join flow.
|
Do NOT use /v1/responses or /hooks/* in this gateway join flow.
|
||||||
|
|
||||||
Body (JSON):
|
Body (JSON):
|
||||||
@@ -1460,6 +1464,7 @@ export function buildInviteOnboardingTextDocument(
|
|||||||
"waitTimeoutMs": 120000,
|
"waitTimeoutMs": 120000,
|
||||||
"sessionKeyStrategy": "fixed",
|
"sessionKeyStrategy": "fixed",
|
||||||
"sessionKey": "paperclip",
|
"sessionKey": "paperclip",
|
||||||
|
"disableDeviceAuth": true,
|
||||||
"role": "operator",
|
"role": "operator",
|
||||||
"scopes": ["operator.admin"]
|
"scopes": ["operator.admin"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,6 +486,8 @@ When you submit the join request, use:
|
|||||||
- \`agentDefaultsPayload.url\` as your \`ws://\` or \`wss://\` gateway URL
|
- \`agentDefaultsPayload.url\` as your \`ws://\` or \`wss://\` gateway URL
|
||||||
- \`agentDefaultsPayload.headers["x-openclaw-token"]\` with your gateway token
|
- \`agentDefaultsPayload.headers["x-openclaw-token"]\` with your gateway token
|
||||||
- (legacy accepted) \`agentDefaultsPayload.headers["x-openclaw-auth"]\`
|
- (legacy accepted) \`agentDefaultsPayload.headers["x-openclaw-auth"]\`
|
||||||
|
- For stock smoke/dev onboarding: set \`agentDefaultsPayload.disableDeviceAuth = true\` to avoid repeated pairing prompts.
|
||||||
|
- If keeping device auth enabled, provide a stable \`agentDefaultsPayload.devicePrivateKeyPem\`; otherwise a new ephemeral device ID may require pairing every run.
|
||||||
|
|
||||||
Do NOT use \`/v1/responses\` or \`/hooks/*\` in this join flow.
|
Do NOT use \`/v1/responses\` or \`/hooks/*\` in this join flow.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user