Skip to content

broker: accept org IDs in deprecated workspace alias schema#199

Closed
benvinegar wants to merge 2 commits intomainfrom
fix/broker-orgid-workspace-schema
Closed

broker: accept org IDs in deprecated workspace alias schema#199
benvinegar wants to merge 2 commits intomainfrom
fix/broker-orgid-workspace-schema

Conversation

@benvinegar
Copy link
Member

Summary

  • fix env schema mismatch causing ❌ baudbot broker register requires root. Run: sudo baudbot broker register to fail validation
  • allow deprecated workspace alias vars to accept org IDs as plain strings
  • add regression coverage in so schema cannot regress to

Root cause

intentionally mirrors org ID into for backward compatibility. The schema still enforced on that deprecated key, causing false config failures.

Verification

  • ✔ parseArgs parses long-form options (0.737185ms)
    ✔ parseArgs accepts --workspace-id as backward-compatible alias for --org-id (0.09017ms)
    ✔ parseArgs sets verbose=true for -v and --verbose (0.064ms)
    ✔ isMainModule handles symlink argv path (0.337995ms)
    ✔ parseArgs accepts registration token (0.066274ms)
    ✔ parseArgs rejects unknown arguments (0.208462ms)
    ✔ parseArgs rejects legacy auth-code argument (0.058329ms)
    ✔ validation helpers normalize and enforce broker/org formats (0.18087ms)
    ✔ mapRegisterError returns actionable messages (0.17022ms)
    ✔ registerWithBroker fetches pubkeys then posts registration payload (1.861459ms)
    ✔ registerWithBroker sends registration_token when provided (0.342795ms)
    ✔ runRegistration integration path succeeds against live local HTTP server (18.70844ms)
    ✔ env schema accepts org IDs for deprecated workspace aliases (0.195688ms)
    ⚠️ Agent restart failed — run: sudo baudbot restart
    ✅ Agent restarted.
    ✔ runRegistration does not write SLACK_BOT_TOKEN even when broker returns encrypted_bot_token (2.169107ms)
    ✔ runRegistration requires registration token (0.13865ms)
    ✔ upsertEnvContent updates existing values and appends new ones (0.184126ms)
    ✔ lookupUser parses passwd entries correctly (0.100188ms)
    ✔ resolveConfigTargets uses BAUDBOT_CONFIG_USER when set (0.178956ms)
    ✔ resolveConfigTargets throws for unknown BAUDBOT_CONFIG_USER (0.072226ms)
    ✔ parseArgs accepts --no-restart flag (0.027422ms)
    ✔ parseArgs defaults noRestart to false (0.020098ms)
    ✔ restartAgent returns false and warns when execFileSync fails (0.113533ms)
    ✔ restartAgent calls systemctl restart baudbot on success (0.073739ms)
    ℹ tests 23
    ℹ suites 0
    ℹ pass 23
    ℹ fail 0
    ℹ cancelled 0
    ℹ skipped 0
    ℹ todo 0
    ℹ duration_ms 77.780798

baudbot@0.1.0 lint
npm run lint:js && npm run lint:shell

baudbot@0.1.0 lint:js
biome lint

Checked 43 files in 21ms. No fixes applied.

baudbot@0.1.0 lint:shell
bash bin/lint-shell.sh

✅ ShellCheck passed (61 files)

baudbot@0.1.0 test
vitest run --config vitest.config.mjs

RUN v4.0.18 /home/bentlegen/Projects/baudbot-beta

✓ test/shell-scripts.test.mjs (13 tests) 28955ms
✓ subagents cli 28450ms
✓ test/broker-bridge.integration.test.mjs (13 tests) 2587ms
✓ pi/extensions/agent-spawn.test.mjs (4 tests) 1034ms
✓ returns readiness timeout and does not issue cleanup commands 1003ms
✓ test/legacy-node-tests.test.mjs (5 tests) 794ms
✓ extension scanner 501ms
✓ test/security-audit.test.mjs (3 tests) 250ms
✓ test/github-events.test.mjs (1 test) 65ms
✓ test/integrity-status-check.test.mjs (3 tests) 48ms
✓ pi/extensions/subagent-manager.test.mjs (4 tests) 6ms
✓ pi/extensions/heartbeat.test.mjs (73 tests) 4ms
✓ pi/extensions/memory.test.mjs (49 tests) 4ms
✓ pi/extensions/subagent-util.test.mjs (2 tests) 4ms

Test Files 11 passed (11)
Tests 170 passed (170)
Start at 21:28:59
Duration 34.81s (transform 89ms, setup 0ms, import 450ms, tests 33.75s, environment 1ms)

  • DigitalOcean Arch droplet end-to-end check:

    • passes after registration

@greptile-apps
Copy link

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR migrates the baudbot broker integration from Slack workspace IDs (T...) to broker org IDs (org_...), fixing a validation failure introduced when the registration flow started mirroring org IDs into deprecated workspace alias env vars. The change introduces GATEWAY_BROKER_ORG_ID/SLACK_BROKER_ORG_ID as the new canonical keys, relaxes the string(startsWith=T) schema constraint on the deprecated workspace alias keys, and propagates the org ID rename across the CLI, broker-bridge, startup scripts, doctor, and config tooling — while keeping workspace_id in the wire protocol and legacy env vars populated for backward compatibility.

Key changes:

  • .env.schema: Adds new preferred GATEWAY_BROKER_ORG_ID/SLACK_BROKER_ORG_ID keys and relaxes type annotation on deprecated workspace alias keys from string(startsWith=T) to plain string.
  • bin/broker-register.mjs: Replaces workspaceId/validateWorkspaceId with orgId/validateOrgId using a broader regex; sends both org_id and workspace_id in the registration payload for broker API compatibility.
  • gateway-bridge/env-aliases.mjs: Adds a resolution block that picks SLACK_BROKER_ORG_ID from the four possible env vars in priority order and back-populates the legacy workspace key — however, this interacts with the existing general alias loop to produce contradictory deprecation guidance for SLACK_BROKER_WORKSPACE_ID (see inline comment).
  • gateway-bridge/broker-bridge.mjs: All signing/polling/acking operations now use brokerOrgId; envelope verification accepts either org_id or workspace_id from the broker envelope.
  • Shell scripts (install.sh, startup-pi.sh, baudbot-runtime.sh, doctor.sh, config.sh): Updated org-ID detection conditions throughout.

Confidence Score: 4/5

  • Safe to merge; the core bug fix and backward-compat logic are correct, with one non-blocking UX issue in deprecation warning guidance.
  • The migration logic is internally consistent: alias resolution correctly populates SLACK_BROKER_ORG_ID from any of the four legacy/new vars before the required-key check runs, existing installations with SLACK_BROKER_WORKSPACE_ID will continue working, and the wire protocol stays backward compatible. The one real issue is that the general alias loop still includes GATEWAY_BROKER_WORKSPACE_ID in GATEWAY_ENV_ALIAS_PAIRS, causing it to emit a warning directing legacy users toward a key that is itself deprecated — contradicting the more specific warning generated by the new custom block. This is a user-facing confusion issue but does not break functionality.
  • gateway-bridge/env-aliases.mjs — contradictory deprecation warnings for SLACK_BROKER_WORKSPACE_ID users

Important Files Changed

Filename Overview
gateway-bridge/env-aliases.mjs Adds org-ID-aware resolution logic below the general alias loop; contradictory deprecation warnings can fire for legacy SLACK_BROKER_WORKSPACE_ID users since the general loop still directs them to the also-deprecated GATEWAY_BROKER_WORKSPACE_ID key.
bin/broker-register.mjs Replaces workspaceId with orgId throughout; broadens ORG_ID_RE regex; adds GATEWAY_BROKER_URL and new org-ID env-var lookups; keeps workspace_id in the wire payload for backward compat. Logic is sound.
gateway-bridge/broker-bridge.mjs Replaces workspaceId with brokerOrgId resolved from SLACK_BROKER_ORG_ID with SLACK_BROKER_WORKSPACE_ID fallback; sends both org_id and workspace_id fields for broker compatibility; updated verifyBrokerEnvelope to accept either field.
gateway-bridge/env-aliases.test.mjs Adds three new tests for org-ID alias resolution; tests do not assert the absence of the contradictory legacy-workspace warning that fires alongside the new deprecation warning.
test/broker-bridge.integration.test.mjs Updated to use SLACK_BROKER_ORG_ID env var and now asserts both org_id and workspace_id fields in ack/pull payloads; comprehensive coverage of the migration.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Env at startup] --> B{applyGatewayEnvAliases}

    B --> C{GATEWAY_BROKER_ORG_ID set?}
    C -- yes --> D[resolved.SLACK_BROKER_ORG_ID = GATEWAY value]
    C -- no --> E{SLACK_BROKER_ORG_ID set?}
    E -- yes --> F[resolved.SLACK_BROKER_ORG_ID = SLACK value]
    E -- no --> G{GATEWAY_BROKER_WORKSPACE_ID set?}
    G -- yes --> H[resolved.SLACK_BROKER_ORG_ID = GATEWAY workspace value\n⚠️ deprecated warning]
    G -- no --> I{SLACK_BROKER_WORKSPACE_ID set?}
    I -- yes --> J[resolved.SLACK_BROKER_ORG_ID = SLACK workspace value\n⚠️ deprecated warning\n⚠️ ALSO general alias warning → GATEWAY_BROKER_WORKSPACE_ID]
    I -- no --> K[brokerOrgId = empty]

    D & F & H & J --> L[resolved.SLACK_BROKER_WORKSPACE_ID = brokerOrgId]
    L --> M[process.env mutated]

    M --> N{Required key check:\nSLACK_BROKER_ORG_ID present?}
    N -- yes --> O[broker-bridge.mjs starts]
    N -- no --> P[process.exit 1]
Loading

Last reviewed commit: 71d2d1b

Comment on lines +96 to +101
} else if (hasGatewayWorkspaceId) {
brokerOrgId = String(gatewayWorkspaceId);
warnings.push("⚠️ GATEWAY_BROKER_WORKSPACE_ID is deprecated; use GATEWAY_BROKER_ORG_ID.");
} else if (hasSlackWorkspaceId) {
brokerOrgId = String(slackWorkspaceId);
warnings.push("⚠️ SLACK_BROKER_WORKSPACE_ID is deprecated; use GATEWAY_BROKER_ORG_ID/SLACK_BROKER_ORG_ID.");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contradictory deprecation warnings for SLACK_BROKER_WORKSPACE_ID

When only SLACK_BROKER_WORKSPACE_ID is set (the common legacy case), users will receive two contradictory warnings:

  1. From the general alias loop at the top of resolveGatewayEnvAliases (since ["GATEWAY_BROKER_WORKSPACE_ID", "SLACK_BROKER_WORKSPACE_ID"] is still in GATEWAY_ENV_ALIAS_PAIRS):

    "Using legacy SLACK_* env vars (SLACK_BROKER_WORKSPACE_ID→GATEWAY_BROKER_WORKSPACE_ID); set GATEWAY_* aliases instead"

    This tells the user to migrate to GATEWAY_BROKER_WORKSPACE_ID — but that key is also deprecated in this PR.

  2. From the new custom block here:

    "SLACK_BROKER_WORKSPACE_ID is deprecated; use GATEWAY_BROKER_ORG_ID/SLACK_BROKER_ORG_ID."

    This is the correct guidance.

A user following warning #1 would set another deprecated key (GATEWAY_BROKER_WORKSPACE_ID) and trigger the same situation again. The existing test ("falls back from deprecated workspace id when org id is absent") only asserts the second warning is present — it does not assert the absence of the first misleading one.

Consider filtering out workspace ID pairs from legacyFallbackKeys when the new org-ID resolution block has already emitted a more specific warning, or moving the workspace/org ID handling entirely out of GATEWAY_ENV_ALIAS_PAIRS into the custom block below.

Prompt To Fix With AI
This is a comment left during a code review.
Path: gateway-bridge/env-aliases.mjs
Line: 96-101

Comment:
**Contradictory deprecation warnings for `SLACK_BROKER_WORKSPACE_ID`**

When only `SLACK_BROKER_WORKSPACE_ID` is set (the common legacy case), users will receive two **contradictory** warnings:

1. From the general alias loop at the top of `resolveGatewayEnvAliases` (since `["GATEWAY_BROKER_WORKSPACE_ID", "SLACK_BROKER_WORKSPACE_ID"]` is still in `GATEWAY_ENV_ALIAS_PAIRS`):
   > "Using legacy SLACK_* env vars (SLACK_BROKER_WORKSPACE_ID→GATEWAY_BROKER_WORKSPACE_ID); set GATEWAY_* aliases instead"

   This tells the user to migrate to `GATEWAY_BROKER_WORKSPACE_ID` — but that key is **also deprecated** in this PR.

2. From the new custom block here:
   > "SLACK_BROKER_WORKSPACE_ID is deprecated; use GATEWAY_BROKER_ORG_ID/SLACK_BROKER_ORG_ID."

   This is the correct guidance.

A user following warning #1 would set another deprecated key (`GATEWAY_BROKER_WORKSPACE_ID`) and trigger the same situation again. The existing test (`"falls back from deprecated workspace id when org id is absent"`) only asserts the second warning is present — it does not assert the absence of the first misleading one.

Consider filtering out workspace ID pairs from `legacyFallbackKeys` when the new org-ID resolution block has already emitted a more specific warning, or moving the workspace/org ID handling entirely out of `GATEWAY_ENV_ALIAS_PAIRS` into the custom block below.

How can I resolve this? If you propose a fix, please make it concise.

@benvinegar
Copy link
Member Author

Closed for #200

@benvinegar benvinegar closed this Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant