Forge has a dedicated Slack app and connector. It is not part of AIEBot: AIEBot
belongs to the neighboring aietools repository and serves AI Engineer
operations, while the Forge app exposes repo-scoped Forge coding agents.
The connector's dedicated D1 database is authoritative for Slack event dedupe, immutable Slack-thread-to-repository bindings, pending delivery, lifecycle events, and repair state. Forge's main D1 is authoritative for installations, encrypted bot tokens, Forge/Slack user links, explicit repository grants, service-principal generations, rotation and revocation ledgers, messages, exact source SHA, budgets, receipts, and run state.
The Slack Worker resolves installation and user authority through the named
SlackIntegrationControl Worker RPC entrypoint on cloudforge-api. The RPC
entrypoint is not mounted on the public HTTP router, and the connector never
receives direct database access. For an authorized turn it receives only that
workspace's bot token and that user/owner boundary's least-privilege Forge API
key. The subsequent Repository Agent call uses the same public API contract
available to customers.
The Worker acknowledges a signed Slack event only after inserting a durable job. A Cloudflare Workflow owns each runnable turn, while a one-minute cron repairs lost dispatches and expired leases. Turns within one Slack thread are serialized; later turns remain queued without consuming their processing deadline. Pending prompt text is cleared as soon as Forge durably accepts the message. Prompts and secret values are never logged.
Each linked Forge user gets a least-privilege service principal for each personal or organization owner boundary they explicitly grant. Its encrypted connector key expires after 30 days and is scheduled for rotation after 25 days. The main Forge API—not the Slack Worker—owns rotation authority.
The minute maintenance loop uses a leased D1 rotation outbox and records key version plus predecessor/successor lineage. It creates one successor, updates the encrypted link credential with a compare-and-swap on the predecessor ID, then decrypts the current consumer value and authenticates it against the service-principal store. Only after that proof receives an immutable receipt does Forge revoke the predecessor. A crash in any phase is resumed from the outbox; an unprovable successor leaves the predecessor active. Overlapping maintainers cannot claim the same link generation.
Uninstall and unlink requests first fence Slack credential resolution and enqueue every affected principal in a separate revocation outbox. That outbox uses bounded leases and backoff, treats an already-revoked principal as success, and records an immutable terminal failure after 20 attempts. Therefore a request crash cannot silently leave a still-resolvable connector credential, and eventual authority revocation remains auditable.
Disconnect also enqueues a private connector-cleanup operation in the same D1
transaction. The Slack Worker claims cleanup jobs through its existing private
SlackIntegrationControl RPC, deletes the exact link's jobs and immutable
thread bindings locally, then acknowledges completion. The minute repair loop
retries any crash between the authority fence and connector deletion. Workspace
uninstall deletes the complete installation transport partition. Keeping the
binding one-way also avoids a first-deploy dependency cycle between the Workers.
chat:write and im:history.OWNER/REPO your question.agent_thread_... Forge thread.agent:read, agent:message, and
agent:run on explicitly granted repositories.From Forge Settings, a signed-in user can install Forge into a Slack workspace, link the installing Slack identity, and explicitly grant repositories they own or administer. Another Slack user who messages an installed bot receives a single-use Forge identity-link URL before any repository agent can run. A linked user who names an ungranted repository receives grant guidance rather than another identity challenge.
The manifest subscribes only to direct messages and Slack credential lifecycle
events. app_uninstalled, tokens_revoked, and team_access_revoked are
persisted in the connector before acknowledgement, fenced in Forge, and retried
by the one-minute repair loop. Each lifecycle job captures both Slack's event
time and the current Forge installation generation. A delayed event cannot
revoke a newer reinstall, while a retry for the same generation is idempotent.
Terminal jobs otherwise expire
after 90 days. Binding rows cannot be updated in place, but explicit
privacy/uninstall deletion is supported.
Slack's own OAuth token rotation remains disabled in this release. Forge still rotates the per-user service-principal keys described above; Slack bot-token rotation needs a separate refresh-token lifecycle and is not implied by that Forge credential policy.
Create a separate D1 database and replace the placeholder ID in
packages/slack-agent/wrangler.toml, then apply its package-local migration.
The Slack Worker requires only these encrypted secrets:
SLACK_APP_IDSLACK_SIGNING_SECRETThe main API requires:
SLACK_APP_IDSLACK_CLIENT_IDSLACK_CLIENT_SECRETSLACK_OAUTH_STATE_SECRETSECRET_ENCRYPTION_KEYNever add any of those values to source control. Install the checked-in Slack
manifest at config/slack/forge-agent.yaml. Its OAuth callback is
https://forge.smol.ai/api/integrations/slack/oauth/callback; its Events API
request URL is https://slack.forge.smol.ai/slack/events. Bot tokens and Forge
service-principal keys are encrypted control-plane data, not Worker secrets.
The only cross-Worker binding is Slack Worker FORGE_CONTROL → API
SlackIntegrationControl. Cleanup uses claim/ack methods on that same private
entrypoint; no API → Slack binding or public cleanup endpoint exists.