diff --git a/console/config/main.php b/console/config/main.php index 1370df98..91c93bd4 100644 --- a/console/config/main.php +++ b/console/config/main.php @@ -6,6 +6,11 @@ require(__DIR__ . '/params-local.php') ); +$consoleSlackWebhookUrl = getenv('CONSOLE_SLACK_WEBHOOK_URL'); +if (!$consoleSlackWebhookUrl) { + $consoleSlackWebhookUrl = getenv('SLACK_WEBHOOK_URL') ?: ''; +} + return [ 'id' => 'app-console', 'basePath' => dirname(__DIR__), @@ -26,7 +31,7 @@ 'slack' => [ 'class' => 'understeam\slack\Client', - 'url' => 'https://hooks.slack.com/services/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', + 'url' => $consoleSlackWebhookUrl, 'username' => 'StudentHub', ], 'log' => [ diff --git a/docs/console-slack-env.md b/docs/console-slack-env.md new file mode 100644 index 00000000..419ef739 --- /dev/null +++ b/docs/console-slack-env.md @@ -0,0 +1,18 @@ +# Console Slack Webhook Configuration + +The console app reads Slack webhook URLs from runtime environment variables instead of storing a webhook in `console/config/main.php`. + +## Variables + +- `CONSOLE_SLACK_WEBHOOK_URL`: Optional console-specific Slack incoming webhook URL. +- `SLACK_WEBHOOK_URL`: Shared fallback webhook URL used when `CONSOLE_SLACK_WEBHOOK_URL` is not set. + +Store these values in the deployment secret manager or in local environment files that are excluded from source control. Do not commit full Slack webhook URLs. + +## Regression Check + +Run the console Slack hardening check before opening config changes: + +```bash +python scripts/check-console-slack-hardening.py +``` diff --git a/scripts/check-console-slack-hardening.py b/scripts/check-console-slack-hardening.py new file mode 100644 index 00000000..8ce69d38 --- /dev/null +++ b/scripts/check-console-slack-hardening.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +"""Validate that console Slack webhook config stays environment-backed.""" + +import re +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +CONSOLE_CONFIG = ROOT / "console" / "config" / "main.php" + + +def main() -> int: + """Return a non-zero exit code when console Slack hardening regresses.""" + + text = CONSOLE_CONFIG.read_text(encoding="utf-8") + failures = [] + + if "hooks.slack.com/services" in text: + failures.append("console/config/main.php still contains a Slack webhook URL") + + if "CONSOLE_SLACK_WEBHOOK_URL" not in text: + failures.append("console/config/main.php does not read CONSOLE_SLACK_WEBHOOK_URL") + + if "SLACK_WEBHOOK_URL" not in text: + failures.append("console/config/main.php does not include the shared SLACK_WEBHOOK_URL fallback") + + if not re.search(r"['\"]url['\"]\s*=>\s*\$consoleSlackWebhookUrl\b", text): + failures.append("console/config/main.php does not wire the Slack client URL through the env-backed value") + + if failures: + print("Console Slack webhook hardening check failed:") + for failure in failures: + print(f"- {failure}") + return 1 + + print("Console Slack webhook hardening check passed.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())