UNPKG

@sellable/install

Version:

One-command installer for Sellable MCP in Claude Code, Codex, and Hermes

153 lines (118 loc) • 5.94 kB
# Hermes Slack Profile Scoping Use this when creating or updating customer Hermes profiles that need Slack access. ## Default Rule For Sellable-managed customer channels, use one dedicated Slack app/token pair per active Hermes customer profile. Run native `hermes -p <profile> gateway run` for that profile only. Do not run multiple active Hermes profile gateways against the same `SLACK_APP_TOKEN`. The customer's Slack app is bound to the exact Slack channel id and the customer's profile-local Sellable MCP config. Customer profiles must not store or read Sellable Admin MCP credentials, admin Slack app tokens, or sibling profile config. The 2026-07-06 Hostinger POC proved the native Hermes listener for the `sellable-admin` profile with the existing `Sellable Reply Bot` app in `#team-chat`: a human mention produced a new Hermes session and a threaded bot reply. Treat that as proof that the gateway/listener path works for one owning profile, not as approval for multiple active customer profiles sharing one app token. The same day, the `acme` profile reused the same redacted Slack token fingerprints for an outbound-only smoke to `#sellable-acme` via: ```bash hermes --profile acme send --to slack:C0BFERDV3N0 --subject '[Hermes acme smoke]' ... ``` That succeeded and is useful as an internal smoke test. It does not change the inbound listener rule: each active customer profile needs its own native Slack app token pair. ## Which Slack Values Are Enough For outbound sends and ordinary Slack Web API calls, the important value is the profile-local `SLACK_BOT_TOKEN`. For native Hermes live listening through Slack Socket Mode, the profile also needs `SLACK_APP_TOKEN`, an app-level `xapp-...` token with `connections:write`. `SLACK_APP_ID`, `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `SLACK_SIGNING_SECRET`, `SLACK_VERIFICATION_TOKEN`, `SLACK_TEAM_ID`, and `SLACK_OPERATOR_EMAIL` do not replace `SLACK_APP_TOKEN`. ## Required Slack App Shape Outbound Slack sends can work with fewer permissions. Native Hermes inbound listening needs the Slack app itself to be configured for Socket Mode and event delivery: - Enable Socket Mode. - Create an app-level token with `connections:write`. - Install the bot with `app_mentions:read`, `channels:history`, `channels:read`, `chat:write`, `groups:history`, `groups:read`, `im:history`, `im:read`, `mpim:history`, `mpim:read`, and `users:read`. - Subscribe bot events for `app_mention`, `message.channels`, `message.groups`, `message.im`, and `message.mpim`. - Reinstall the app after changing scopes or event subscriptions. If the Slack app has `incoming-webhook`, Slack will ask for a webhook channel during reinstall. Pick the profile home channel. That webhook selection does not replace `SLACK_ALLOWED_CHANNELS`; keep the profile-local allowlist explicit. ## Profile Bootstrap Command Use the Sellable installer profile bootstrap: ```bash sellable hermes profile bootstrap \ --profile acme \ --profiles-root /srv/hermes/profiles \ --workspace-id ws_acme \ --workspace-name Acme \ --token-file /run/secrets/sellable-acme-token \ --slack-bot-token "$SLACK_BOT_TOKEN" \ --slack-app-token "$SLACK_APP_TOKEN" \ --slack-home-channel C0ACME12345 \ --slack-home-channel-name sellable-acme \ --slack-allowed-users U0OPERATOR1 \ --slack-require-mention true \ --json ``` If `--slack-home-channel` is supplied and `--slack-allowed-channels` is omitted, the installer writes `SLACK_ALLOWED_CHANNELS=<home-channel-id>` automatically. That makes the profile fail closed to the customer channel by default. Use `--slack-allowed-channels C...,G...` only when a profile is intentionally allowed to listen in more than one channel. Pass Slack IDs, not `#channel-name` strings or wildcards. ## Resulting Profile Env For the dedicated customer Slack app model, the profile-local `.env` should contain only scoped Slack keys for that profile: ```env SLACK_BOT_TOKEN=... SLACK_APP_TOKEN=... SLACK_HOME_CHANNEL=C0ACME12345 SLACK_HOME_CHANNEL_NAME=sellable-acme SLACK_ALLOWED_CHANNELS=C0ACME12345 SLACK_ALLOWED_USERS=U0OPERATOR1 SLACK_REQUIRE_MENTION=true ``` Keep the file mode at `0600`. Do not copy raw tokens into planning docs, chat, or committed artifacts. Record token fingerprints only. The profile's Hermes MCP env must also include the profile-local Sellable config, customer workspace lock, and fail-closed guard: ```yaml SELLABLE_CONFIG_PATH: /srv/hermes/profiles/acme/sellable/config.json SELLABLE_CONFIGS_DIR: /srv/hermes/profiles/acme/sellable/configs SELLABLE_LOCK_WORKSPACE_ID: ws_acme SELLABLE_REQUIRE_WORKSPACE_LOCK: "1" ``` `SELLABLE_REQUIRE_WORKSPACE_LOCK=1` means an unbound customer profile fails closed before making Sellable API calls instead of falling back to shared or admin config state. Only the `sellable-admin` profile should provision, inspect, or repair other profiles. ## Verification Run the installer and native profile UAT before publishing installer changes: ```bash npm run test:unit -- tests/install-package/agent-preferences.test.ts scripts/run-phase92-hermes-profile-bootstrap-uat.sh --mode local-temp scripts/run-phase92-hermes-profile-bootstrap-uat.sh --mode linux-shaped ``` Expected proof: - profile-local Sellable config paths remain authoritative - generated profile `.env` has `SLACK_HOME_CHANNEL` - generated profile `.env` has `SLACK_ALLOWED_CHANNELS` - `acme` allowlist points at the `sellable-acme` fixture channel id - redaction scan passes ## Current Phase 03 Status Phase 03 proved the profile-scoped installer path, outbound Hermes send path, and live Slack listener for the `sellable-admin` profile. Phase 03.1 now targets dedicated native Slack apps per customer profile, profile-local Sellable MCP locks, and fail-closed customer profile behavior so managed customer channels can be onboarded through the VPS without local-only browser state, manual SSH edits, or untracked processes.