This guide walks through creating a Slack app for github-ops-app notifications.
- Slack workspace with admin access (or ability to request app approval)
- Channel where notifications will be posted
- Go to api.slack.com/apps
- Click Create New App
- Select From an app manifest
- Select your workspace
- Copy the contents of
assets/slack/manifest.jsonand paste into the manifest editor - Click Create
- Go to api.slack.com/apps
- Click Create New App → From scratch
- Enter app name:
GitHub Ops Bot - Select your workspace
- Click Create App
Then continue to configure OAuth scopes manually (Step 2).
If you used the manifest, scopes are pre-configured. Otherwise:
-
Go to OAuth & Permissions in the sidebar
-
Scroll to Scopes → Bot Token Scopes
-
Add the following scopes:
Scope Purpose chat:writePost messages to channels bot is member of chat:write.publicPost to public channels without joining channels:readView basic channel info channels:joinJoin public channels
- Go to OAuth & Permissions
- Click Install to Workspace
- Review permissions and click Allow
If your workspace requires admin approval:
- Submit the app for approval
- Wait for workspace admin to approve
- Return to install after approval
After installation:
- Go to OAuth & Permissions
- Copy the Bot User OAuth Token
- Starts with
xoxb- - Example:
xoxb-1234567890-...
- Starts with
This is your APP_SLACK_TOKEN.
You need the channel ID (not the name) for APP_SLACK_CHANNEL.
- Open Slack in a browser or desktop app
- Right-click the channel name
- Select View channel details (or Open channel details)
- Scroll to the bottom - Channel ID is shown (e.g.,
C01ABC2DEFG)
- Right-click the channel name
- Select Copy link
- The link contains the channel ID:
https://workspace.slack.com/archives/C01ABC2DEFG
curl -H "Authorization: Bearer xoxb-your-token" \
"https://slack.com/api/conversations.list?types=public_channel,private_channel" \
| jq '.channels[] | select(.name=="your-channel-name") | .id'For private channels, you must invite the bot:
- Open the private channel
- Type
/invite @GitHub Ops Bot(or your bot's display name) - Or click the channel name → Integrations → Add apps
Public channels work without invitation when using chat:write.public.
# Required Slack configuration
APP_SLACK_TOKEN=xoxb-1234567890-...
APP_SLACK_CHANNEL=C01ABC2DEFG
# Optional: per-notification-type channels (override APP_SLACK_CHANNEL)
APP_SLACK_CHANNEL_PR_BYPASS=C01234ABCDE
APP_SLACK_CHANNEL_OKTA_SYNC=C01234ABCDE
APP_SLACK_CHANNEL_ORPHANED_USERS=C01234ABCDE
APP_SLACK_CHANNEL_SECURITY_ALERTS=C01234ABCDEFor AWS deployments, use SSM parameters:
APP_SLACK_TOKEN=arn:aws:ssm:us-east-1:123456789:parameter/github-bot/slack-tokenMake notifications more recognizable:
- Go to Basic Information
- Under Display Information:
- App name:
GitHub Ops Bot(or your preference) - Short description: Brief description of the bot
- App icon: Upload a custom icon (use
assets/slack/icon.pngor your own) - Background color:
#10203Bor your brand color
- App name:
Test your Slack configuration:
# Test message posting
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer xoxb-your-token" \
-H "Content-Type: application/json" \
-d '{
"channel": "C01ABC2DEFG",
"text": "GitHub Bot test message"
}'Expected response:
{
"ok": true,
"channel": "C01ABC2DEFG",
"ts": "1234567890.123456",
"message": { ... }
}The bot sends these notification types:
| Event | Description |
|---|---|
| PR Compliance Alert | PR merged bypassing branch protection |
| Okta Sync Report | Summary of team membership changes |
| Orphaned Users Alert | Org members not in any synced teams |
| Security Alerts Report | Stale security alerts across the org |
| Sync Error | Errors during Okta sync process |
- Bot needs to be in the channel to post
- For private channels:
/invite @GitHub Bot - For public channels: Ensure
chat:write.publicscope is granted
- Token may be expired or revoked
- Regenerate token: OAuth & Permissions → Reinstall to Workspace
- Verify token starts with
xoxb-
- Verify channel ID is correct (not channel name)
- Channel IDs start with
C(public),G(private), orD(DM) - Check the channel still exists
- Add the required scope in OAuth & Permissions
- Reinstall the app after adding scopes
- Check the channel ID is correct
- Verify bot is in the channel (for private channels)
- Check app logs for API response errors
- Test with curl command above to isolate the issue
Slack has rate limits (typically 1 message per second per channel). The app handles rate limits gracefully, but if you see delays:
- Notifications are queued and retried
- Consider consolidating notifications for high-volume events
- Token security: Store
APP_SLACK_TOKENsecurely (environment variable, SSM parameter, or secrets manager) - Channel access: Bot can only post to channels it has access to
- No incoming webhooks: This setup uses bot tokens, not incoming webhooks, providing better security and audit trails
- Minimal scopes: Only request scopes actually needed