mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(crabbox): require broker auth for aws proof
This commit is contained in:
@@ -630,7 +630,7 @@ Install/auth for owned Crabbox if needed:
|
||||
|
||||
```sh
|
||||
brew install openclaw/tap/crabbox
|
||||
crabbox login --url https://crabbox.openclaw.ai --provider aws
|
||||
crabbox login --provider aws
|
||||
```
|
||||
|
||||
New users should self-resolve broker auth before anyone asks for AWS keys:
|
||||
@@ -641,7 +641,7 @@ crabbox doctor
|
||||
crabbox whoami
|
||||
```
|
||||
|
||||
- If broker auth is missing, run `crabbox login --url https://crabbox.openclaw.ai --provider aws`.
|
||||
- If broker auth is missing, run `crabbox login --provider aws`.
|
||||
- If the CLI asks for `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, or AWS
|
||||
profile setup during normal OpenClaw validation, assume the agent selected
|
||||
the wrong path. Use brokered `crabbox login` or an existing brokered lease
|
||||
@@ -649,7 +649,7 @@ crabbox whoami
|
||||
- Ask for AWS keys only for explicit direct-provider/account administration,
|
||||
not for normal brokered OpenClaw proof.
|
||||
- Trusted automation may still use
|
||||
`printf '%s' "$CRABBOX_COORDINATOR_TOKEN" | crabbox login --url https://crabbox.openclaw.ai --provider aws --token-stdin`.
|
||||
`printf '%s' "$CRABBOX_COORDINATOR_TOKEN" | crabbox login --provider aws --token-stdin`.
|
||||
|
||||
macOS config lives at:
|
||||
|
||||
|
||||
@@ -175,6 +175,7 @@ function checkedOutput(command, commandArgs) {
|
||||
return {
|
||||
status: result.status ?? 1,
|
||||
text: `${result.stdout ?? ""}${result.stderr ?? ""}`.trim(),
|
||||
stdout: (result.stdout ?? "").trim(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -392,6 +393,48 @@ function selectedProvider(commandArgs) {
|
||||
return commandProvider(commandArgs) || configuredProvider();
|
||||
}
|
||||
|
||||
function shouldRequireBrokeredAws(commandArgs, providerName) {
|
||||
if (process.env.OPENCLAW_CRABBOX_ALLOW_DIRECT_AWS === "1") {
|
||||
return false;
|
||||
}
|
||||
const canonicalProvider = providerAliases.get(providerName) ?? providerName;
|
||||
if (canonicalProvider !== "aws") {
|
||||
return false;
|
||||
}
|
||||
if (commandArgs[0] === "run" || commandArgs[0] === "warmup") {
|
||||
return true;
|
||||
}
|
||||
return commandArgs[0] === "actions" && commandArgs[1] === "hydrate";
|
||||
}
|
||||
|
||||
function brokerAuthConfigured() {
|
||||
const config = checkedOutput(binary, ["config", "show", "--json"]);
|
||||
if (config.status !== 0) {
|
||||
return false;
|
||||
}
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(config.stdout || config.text);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return Boolean(parsed?.coordinator && parsed?.brokerAuth === "configured");
|
||||
}
|
||||
|
||||
function enforceBrokeredAws(commandArgs, providerName) {
|
||||
if (!shouldRequireBrokeredAws(commandArgs, providerName) || brokerAuthConfigured()) {
|
||||
return;
|
||||
}
|
||||
console.error(
|
||||
[
|
||||
"[crabbox] provider=aws requires a configured Crabbox broker for OpenClaw proof.",
|
||||
"[crabbox] run `crabbox login --provider aws`, then retry.",
|
||||
"[crabbox] for intentional direct AWS provider debugging, set OPENCLAW_CRABBOX_ALLOW_DIRECT_AWS=1.",
|
||||
].join("\n"),
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
function optionValue(commandArgs, name) {
|
||||
commandArgs = crabboxOptionArgs(commandArgs);
|
||||
for (let index = 0; index < commandArgs.length; index += 1) {
|
||||
@@ -1722,6 +1765,8 @@ if (provider && !isProviderAdvertised(provider, providers)) {
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
enforceBrokeredAws(normalizedArgs, provider);
|
||||
|
||||
if (provider === "blacksmith-testbox") {
|
||||
const envProvider = process.env.CRABBOX_PROVIDER?.trim();
|
||||
const source = commandProviderValue
|
||||
|
||||
@@ -28,6 +28,15 @@ function writeFakeCrabbox(binDir: string, helpText: string): string {
|
||||
` process.stdout.write(${JSON.stringify(helpText)});`,
|
||||
" process.exit(0);",
|
||||
"}",
|
||||
'if (args[0] === "config" && args[1] === "show" && args.includes("--json")) {',
|
||||
" const status = Number.parseInt(process.env.OPENCLAW_FAKE_CRABBOX_CONFIG_STATUS || '0', 10);",
|
||||
" if (status !== 0) {",
|
||||
" process.stderr.write('config unavailable\\n');",
|
||||
" process.exit(status);",
|
||||
" }",
|
||||
" process.stdout.write(process.env.OPENCLAW_FAKE_CRABBOX_CONFIG_JSON || '{\"coordinator\":\"configured-broker\",\"brokerAuth\":\"configured\"}');",
|
||||
" process.exit(0);",
|
||||
"}",
|
||||
"const scriptIndex = args.findIndex((arg) => arg === '--script' || arg === '-script');",
|
||||
"const scriptPath = scriptIndex >= 0 ? args[scriptIndex + 1] : '';",
|
||||
"const scriptContent = scriptPath ? require('node:fs').readFileSync(scriptPath, 'utf8') : '';",
|
||||
@@ -75,6 +84,9 @@ function runWrapper(
|
||||
helpText: string,
|
||||
args: string[],
|
||||
options: {
|
||||
configJson?: Record<string, unknown>;
|
||||
configStatus?: number;
|
||||
env?: Record<string, string>;
|
||||
extraPathEntries?: string[];
|
||||
gitResponses?: Record<string, { status?: number; stdout?: string; stderr?: string }>;
|
||||
input?: string;
|
||||
@@ -92,6 +104,13 @@ function runWrapper(
|
||||
.filter(Boolean)
|
||||
.join(path.delimiter),
|
||||
OPENCLAW_CRABBOX_WRAPPER_IGNORE_REPO_BINARY: "1",
|
||||
...(options.configJson
|
||||
? { OPENCLAW_FAKE_CRABBOX_CONFIG_JSON: JSON.stringify(options.configJson) }
|
||||
: {}),
|
||||
...(options.configStatus
|
||||
? { OPENCLAW_FAKE_CRABBOX_CONFIG_STATUS: String(options.configStatus) }
|
||||
: {}),
|
||||
...(options.env ?? {}),
|
||||
...(options.gitResponses
|
||||
? { OPENCLAW_FAKE_GIT_RESPONSES: JSON.stringify(options.gitResponses) }
|
||||
: {}),
|
||||
@@ -189,6 +208,40 @@ describe("scripts/crabbox-wrapper", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("fails closed for AWS proof when broker auth is missing", () => {
|
||||
const result = runWrapper(
|
||||
"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
|
||||
["run", "--provider", "aws", "--", "echo ok"],
|
||||
{ configJson: { coordinator: "", brokerAuth: "missing" } },
|
||||
);
|
||||
|
||||
expect(result.status).toBe(2);
|
||||
expect(result.stdout).toBe("");
|
||||
expect(result.stderr).toContain("provider=aws requires a configured Crabbox broker");
|
||||
expect(result.stderr).toContain("crabbox login --provider aws");
|
||||
expect(result.stderr).not.toContain("crabbox.openclaw.ai");
|
||||
});
|
||||
|
||||
it("allows explicit direct AWS debugging without broker auth", () => {
|
||||
const result = runWrapper(
|
||||
"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
|
||||
["run", "--provider", "aws", "--", "echo ok"],
|
||||
{
|
||||
configJson: { coordinator: "", brokerAuth: "missing" },
|
||||
env: { OPENCLAW_CRABBOX_ALLOW_DIRECT_AWS: "1" },
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(parseFakeCrabboxOutput(result).args).toEqual([
|
||||
"run",
|
||||
"--provider",
|
||||
"aws",
|
||||
"--",
|
||||
"echo ok",
|
||||
]);
|
||||
});
|
||||
|
||||
it("defaults AWS macOS warmups to on-demand capacity", () => {
|
||||
const result = runWrapper(
|
||||
"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
|
||||
|
||||
Reference in New Issue
Block a user