A catalogue of Slack Apps¶
Declare Slack Apps in values and create them from the console, as in the GitHub App catalogue.
Before you start¶
-
Connect the
workspacefirst on the Workspaces tab, or Create and Install fail with connect the workspace first. -
Set
config.store: kubernetes. -
The service refuses to start on a bad entry: unknown key, duplicate id, bad scope, or an undeclared
workspace.
1. Declare an App¶
slackApps:
- id: sync # [a-z0-9-], at most 32, unique; never changes
workspace: acme # a key of the policy's slack.workspaces
name: acme-sync # optional; default <workspace>-<id>, at most 35
description: Keeps channels in step with groups # optional; at most 140
botScopes: # the bot token's scopes; at least one
- channels:read
- users:read
- users:read.email
push: # optional; off unless written out
secretStore: {name: example-store, kind: SecretStore}
remoteKey: platform/slack-apps/sync
The chart renders this into ConfigMap <release>-slack-apps-catalogue, read once at start. Scopes use Slack's names, such as conversations.connect:write.
2. Get a configuration token¶
On api.slack.com/apps, signed in to the owning workspace, choose Generate Token under Your App Configuration Tokens. Copy the Access Token (xoxe.xoxp-). It expires in 12 hours, is used once and is never stored or logged.
3. Create and install¶
On the Apps tab (#/slack/apps):
- Create. Paste the token. The manifest has the bot user, the
botScopesand one redirect URL, with no events or interactivity. The App reads created, not installed. - Install. An owner approves on Slack, and the console exchanges the code for the bot token. A token for another team is revoked and the install refused. The App reads installed.
When you add a scope the row says scopes missing. Reinstall needs a fresh token to update the manifest, then an owner approves.
The owning directory's operators, or the installation-wide operator, may do this (ownership).
4. Find the credentials¶
The Secret <release>-slack-catalogue-apps is created empty at start.
| Key | Holds | Exists |
|---|---|---|
<id>.record.json |
Ids, scopes, who and when. Never a credential | From Create |
<id>.client_id |
The OAuth client id | From Create |
<id>.client_secret |
The OAuth client secret | From Create |
<id>.slack_bot_token |
The bot token | From Install only |
Slack has no token exchange, so a consumer reads a copy. With a ports.adapter other than legacy and SSM secrets, read external/slack/<id> (secrets). push is deprecated and applies only to legacy:
push:
secretStore: {name: example-store, kind: ClusterSecretStore} # kind: SecretStore (default) | ClusterSecretStore
remoteKey: platform/slack-apps/sync
refreshInterval: 1h # optional, default 1h
deletionPolicy: None # optional: None (default) | Delete
The consumer reads bot_token at remoteKey; only that key is copied. Rotate by reinstalling. The chart refuses two entries on one remoteKey and push without config.store: kubernetes.
Verify¶
The App reads installed. Audit records roster.slack_app.created, .installed and .install_refused carry no token.
| You see | Fix |
|---|---|
invalid_auth on create |
The configuration token expired, was revoked or is for another workspace. Generate a fresh one |
invalid_manifest on create |
Slack rejected the declaration, usually a name or scope. The detail says where |
| the policy's slack.workspaces does not name workspace | The policy changed under a running service. Restore the key |
| installed into workspace T... and the policy names T... | The owner approved another workspace. Nothing was kept. Remove the App there and install from the right one |
| declares scopes the App was created without | Paste a token and reinstall |
| This install did not start in this browser | Start Install again within ten minutes in the same browser |
Roll back¶
There is no Disconnect. Delete the App at https://api.slack.com/apps/<app id> and remove its keys from the Secret by hand. A removed entry stays listed as no longer declared.
Decided in: ADR 0025.