Skip to content

christauff/mattermost-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mattermost ChatOps Bot

TypeScript/Bun ChatOps bot for Mattermost with script orchestration as the primary feature.

Features

Status: All 6 Phases Complete ✅ - Production Ready

Phase 1: Core Bot

  • ✅ WebSocket connection to Mattermost with auto-reconnect
  • ✅ Exponential backoff reconnection (1s → 60s)
  • ✅ Command parsing and routing
  • ✅ Plugin system for extensibility
  • ✅ Built-in !ping command
  • ✅ Systemd service deployment
  • ✅ Comprehensive test coverage

Phase 2: Script Executor

  • ✅ Script allowlist validation
  • ✅ Argument validation and sanitization
  • ✅ Subprocess execution with timeout enforcement
  • ✅ Output streaming to channels
  • ✅ Local and Ansible remote execution
  • ✅ Audit logging for all script executions

Phase 3: Permission System

  • ✅ SQLite database with migration system
  • ✅ User permission levels (admin, operator, user, banned)
  • ✅ Custom flags (Eggdrop-style)
  • ✅ Permission management commands (!adduser, !deluser, !chattr, !whois)
  • ✅ Permission checks enforced on script execution
  • ✅ Bootstrap admin script for initial setup

Phase 4: Ban Management

  • ✅ Ban/unban commands (!ban, !unban, !banlist)
  • ✅ Temporary and permanent bans
  • ✅ Automatic ban expiration
  • ✅ Router-level enforcement (bans checked before command routing)
  • ✅ Cannot ban admin users (safety feature)

Phase 5: Remote Execution

  • ✅ Ansible playbook integration
  • ✅ SSH key authentication support
  • ✅ Multi-host orchestration
  • ✅ JSON output parsing
  • ✅ Extra vars support for parameterized playbooks

Phase 6: Hardening & Monitoring

  • ✅ Comprehensive audit logging
  • ✅ Supply chain security (frozen lockfile, 3-day package age policy)
  • ✅ SBOM generation and vulnerability scanning
  • ✅ Ed25519 digital signatures on audit logs
  • ✅ Security documentation (SECURITY.md, MONITORING.md, DEPLOYMENT.md)

Requirements

  • Bun >= 1.0
  • Mattermost Server (tested with v9.0+)
  • RHEL 9 (for production deployment)

Quick Start (Development)

1. Install Dependencies

cd ~/projects/mattermost-bot
bun install

2. Configure Bot

# Copy template
cp config/bot.config.json.template config/bot.config.json

# Edit with your Mattermost details
# You'll need:
# - Mattermost server URL
# - Bot account token (see "Create Bot Account" below)
# - Bot user ID

3. Create Bot Account in Mattermost

  1. Log in to Mattermost as System Admin
  2. Go to System Console > Integrations > Bot Accounts
  3. Click Add Bot Account
  4. Fill in:
    • Username: chatops-bot
    • Display Name: ChatOps Bot
    • Description: Script orchestration and channel management
    • Post All: ✅ (required to read messages)
  5. Click Create Bot Account
  6. Copy the Bot Access Token
  7. Copy the Bot User ID (from the bot's profile)

4. Update Configuration

Edit config/bot.config.json:

{
  "mattermost": {
    "url": "https://your-mattermost-server.com",
    "token": "YOUR_BOT_TOKEN_HERE",
    "botUserId": "YOUR_BOT_USER_ID_HERE"
  }
}

5. Run Bot (Development)

bun run bot.ts

You should see:

🤖 Mattermost ChatOps Bot
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 Loading config from: ./config/bot.config.json
✅ Config loaded successfully
🌐 Mattermost URL: https://your-server.com
🔧 Command prefix: !
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[2026-01-27T...] INFO  Connected to Mattermost
[2026-01-27T...] INFO  Bot is ready and listening for commands

6. Test in Mattermost

In any channel where the bot is a member:

!ping

Expected response:

Pong! Bot is alive. 🏓

Running Tests

# All tests
bun test

# Specific component
bun test src/core/bot-client.test.ts
bun test src/core/command-router.test.ts

Production Deployment (RHEL 9)

1. Prerequisites

# Install Bun
curl -fsSL https://bun.sh/install | bash

# Create bot user
sudo useradd -r -s /bin/bash -m -d /opt/mattermost-bot mattermost-bot

# Create directory structure
sudo mkdir -p /opt/mattermost-bot/{src,config,scripts,playbooks,data,logs}

2. Deploy Code

# Copy project to /opt
sudo cp -r ~/projects/mattermost-bot/* /opt/mattermost-bot/

# Install dependencies (CRITICAL: use --frozen-lockfile)
cd /opt/mattermost-bot
sudo -u mattermost-bot bun install --frozen-lockfile --production

# Set ownership
sudo chown -R mattermost-bot:mattermost-bot /opt/mattermost-bot

# Set permissions
sudo chmod 600 /opt/mattermost-bot/config/bot.config.json
sudo chmod +x /opt/mattermost-bot/bot.ts
sudo chmod +x /opt/mattermost-bot/scripts/*.sh

3. Configure Production Settings

# Copy template
sudo -u mattermost-bot cp /opt/mattermost-bot/config/bot.config.json.template \
  /opt/mattermost-bot/config/bot.config.json

# Edit config (use production URLs and tokens)
sudo -u mattermost-bot nano /opt/mattermost-bot/config/bot.config.json

4. Install Systemd Service

# Copy service file
sudo cp /opt/mattermost-bot/mattermost-bot.service /etc/systemd/system/

# Reload systemd
sudo systemctl daemon-reload

# Enable service (start on boot)
sudo systemctl enable mattermost-bot

# Start service
sudo systemctl start mattermost-bot

# Check status
sudo systemctl status mattermost-bot

5. Verify Production Deployment

# CRITICAL: Verify supply chain BEFORE starting bot
cd /opt/mattermost-bot
sudo -u mattermost-bot bun run scripts/verify-supply-chain.ts

# View logs
sudo journalctl -u mattermost-bot -f

# Check if bot is running
systemctl is-active mattermost-bot

# Test bot in Mattermost
# !ping

Project Structure

/opt/mattermost-bot/
├── bot.ts                    # Main entrypoint
├── package.json              # Dependencies
├── tsconfig.json             # TypeScript config
├── mattermost-bot.service    # Systemd service file
├── README.md                 # This file
├── src/
│   ├── core/
│   │   ├── bot-client.ts     # Mattermost WebSocket connection
│   │   ├── command-router.ts # Command parsing and routing
│   │   └── script-executor.ts # (Phase 2) Script execution
│   ├── plugins/              # (Phase 3+) Permission, bans, channel ops
│   ├── database/             # (Phase 3) SQLite wrapper
│   └── utils/
│       ├── logger.ts         # Structured logging
│       ├── config.ts         # Configuration loader
│       └── security.ts       # (Phase 2) Input validation
├── scripts/                  # Allowlisted scripts
│   └── test-script.sh        # Test script for Phase 1
├── config/
│   ├── bot.config.json       # Bot configuration (KEEP SECRET!)
│   └── script-allowlist.json # Approved scripts (Phase 2)
├── data/
│   └── bot.db                # (Phase 3) SQLite database
└── logs/
    ├── bot.log               # Application logs
    └── script-executions.log # (Phase 2) Script execution logs

Configuration Reference

bot.config.json

{
  "mattermost": {
    "url": "https://mattermost.example.com",
    "token": "YOUR_BOT_TOKEN",
    "botUserId": "YOUR_BOT_USER_ID",
    "websocketUrl": "wss://mattermost.example.com/api/v4/websocket"
  },
  "database": {
    "path": "./data/bot.db"
  },
  "logging": {
    "level": "info",
    "file": "./logs/bot.log",
    "console": true
  },
  "scripts": {
    "allowlistPath": "./config/script-allowlist.json",
    "scriptsDir": "./scripts",
    "defaultTimeout": 300000
  },
  "bot": {
    "commandPrefix": "!",
    "reconnectDelay": 1000,
    "maxReconnectDelay": 60000,
    "reconnectBackoff": 2
  }
}

Troubleshooting

Bot won't connect

  1. Check Mattermost URL is correct
  2. Verify bot token is valid
  3. Ensure bot account exists and is not deactivated
  4. Check firewall allows WebSocket connections
# Test connectivity
curl https://your-mattermost-server.com/api/v4/system/ping

# Check bot logs
sudo journalctl -u mattermost-bot -n 100

Bot connects but doesn't respond

  1. Verify bot is member of the channel
  2. Check bot has "Post All" permission
  3. Confirm command prefix matches config (default: !)
  4. Review logs for errors
# Check if bot sees messages
sudo journalctl -u mattermost-bot | grep "Received command"

Service won't start

# Check service status
sudo systemctl status mattermost-bot

# Check logs
sudo journalctl -u mattermost-bot -xe

# Verify config file exists
ls -la /opt/mattermost-bot/config/bot.config.json

# Test bot manually
cd /opt/mattermost-bot
sudo -u mattermost-bot bun run bot.ts

Systemd Management

# Start bot
sudo systemctl start mattermost-bot

# Stop bot
sudo systemctl stop mattermost-bot

# Restart bot
sudo systemctl restart mattermost-bot

# View status
sudo systemctl status mattermost-bot

# View logs (live)
sudo journalctl -u mattermost-bot -f

# View last 100 log lines
sudo journalctl -u mattermost-bot -n 100

# Enable autostart on boot
sudo systemctl enable mattermost-bot

# Disable autostart
sudo systemctl disable mattermost-bot

Development

Watch Mode

bun --watch bot.ts

Run Tests

bun test                                    # All tests
bun test src/core/bot-client.test.ts       # Bot client only
bun test src/core/command-router.test.ts   # Command router only

Type Checking

bun tsc --noEmit

Getting Started with Production Deployment

All 6 phases are complete. The bot is production-ready. Follow these steps:

1. Bootstrap First Admin User

# After deploying to production, create the first admin user
cd /opt/mattermost-bot
sudo -u mattermost-bot bun run scripts/bootstrap-admin.ts <your-mattermost-user-id> <your-username>

2. Test Permission System

# In Mattermost, verify you're an admin
!whois @yourself

# Add an operator user
!adduser @teammate operator

# Add a regular user
!adduser @user user

3. Configure Scripts

Edit config/script-allowlist.json to add your scripts:

{
  "scripts": [
    {
      "name": "deploy",
      "path": "./scripts/deploy.sh",
      "description": "Deploy application to environment",
      "requiredPermission": "operator",
      "timeout": 1800000,
      "allowedChannels": ["ops", "deployments"]
    }
  ]
}

4. Set Up Ansible (Optional)

For remote execution via Ansible:

# Create playbooks directory
mkdir -p /opt/mattermost-bot/playbooks/inventory

# Add your inventory file
cat > /opt/mattermost-bot/playbooks/inventory/hosts << 'EOF'
[staging]
staging-server-1 ansible_host=192.168.1.10

[production]
prod-server-1 ansible_host=10.0.1.10
prod-server-2 ansible_host=10.0.1.11
EOF

# Generate SSH key for bot
sudo -u mattermost-bot ssh-keygen -t ed25519 -f /opt/mattermost-bot/.ssh/id_ed25519_bot

5. Documentation

See detailed documentation:

  • ALL-PHASES-COMPLETE.md - Complete feature verification
  • PHASE3-COMPLETE.md - Permission system details
  • SECURITY.md - Security considerations
  • MONITORING.md - Monitoring setup
  • DEPLOYMENT.md - Deployment procedures

Supply Chain Security

This project implements comprehensive supply chain security measures to protect against dependency attacks.

Security Configuration

bunfig.toml - Bun security settings:

  • frozen = true - Enforces deterministic installs (lockfile not modified)
  • minimumReleaseAge = 259200 - Blocks packages newer than 3 days (defense against rapid-publish attacks)
  • allowScripts = false - Disables lifecycle scripts (postinstall, preinstall) by default

package.json - Trusted dependencies:

  • trustedDependencies: [] - Allowlist for packages that need lifecycle scripts
  • Currently empty - no dependencies require lifecycle scripts

Verification Script

Run supply chain verification before deployment:

bun run scripts/verify-supply-chain.ts

This checks:

  • ✅ Lockfile exists
  • ✅ Lockfile matches package.json (frozen check)
  • ✅ bunfig.toml has security settings
  • ✅ trustedDependencies declared
  • ✅ No vulnerabilities (bun audit)

SBOM Generation

Generate Software Bill of Materials (SBOM) for vulnerability tracking:

# Install syft (first time only)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# Generate SBOM
./scripts/generate-sbom.sh

# Scan for vulnerabilities
grype sbom:sbom.spdx.json

Deployment Requirements

CRITICAL: Always use frozen lockfile in production:

# Production install
bun install --frozen-lockfile --production

# Verify supply chain BEFORE deploying
bun run scripts/verify-supply-chain.ts

minimumReleaseAge Policy

Packages must be published for 3 days before installation. This defends against:

  • Rapid-publish attacks - Attacker publishes malicious version, quickly unpublishes
  • Typosquatting - Malicious packages get caught by community before installation
  • Compromised accounts - Time for maintainers to notice and respond

Exception Process: If you need a package newer than 3 days:

  1. Review package source code on GitHub
  2. Verify publisher identity
  3. Check recent issues/PRs
  4. Temporarily lower minimumReleaseAge in bunfig.toml
  5. Install package
  6. Restore original minimumReleaseAge

Lifecycle Scripts

Lifecycle scripts (postinstall, preinstall) are DISABLED by default in Bun. This prevents malicious code execution during install.

If a package requires lifecycle scripts:

  1. Review the script source code
  2. Add package name to trustedDependencies in package.json
  3. Document why it's trusted (e.g., "Official TypeScript package, 10M+ downloads/month")

Current trusted dependencies: None (all dependencies work without lifecycle scripts)

Audit Logging

All script executions are cryptographically signed and logged to logs/script-executions.log.

Each entry includes:

  • Ed25519 digital signature (tamper-proof)
  • SHA-256 hash chain (detects deletion/reordering)
  • Full execution context (user, script, arguments, exit code)

Verify log integrity:

bun run scripts/verify-audit-log.ts

Security Resources

License

MIT

Support

For issues or questions:

  1. Check logs: sudo journalctl -u mattermost-bot -f
  2. Review configuration: /opt/mattermost-bot/config/bot.config.json
  3. Test manually: sudo -u mattermost-bot bun run /opt/mattermost-bot/bot.ts

About

TypeScript/Bun ChatOps bot for Mattermost with script orchestration as the primary feature.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors