signal-bot/SECURITY.md
Krzysztof kuhy Rudnicki 5d76adf4db feat: watch several groups, and answer only where you were asked
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 15:03:24 +02:00

40 lines
1.7 KiB
Markdown

# Security Policy
## Scope of a linked device
This bot runs as a **linked device** on an existing Signal account. That means
it can read every direct message and every group on that account, and anything
it sends is sent **as the account owner**. It is not a separate identity.
`GROUP_IDS` is the only thing that narrows this. The bot therefore:
- refuses to start when `GROUP_IDS` is missing or blank, rather than
defaulting to an empty string that matches nothing predictably;
- drops messages with no `groupInfo` (direct messages) explicitly, in
`counting.watched_group`, rather than relying on a falsy comparison;
- resolves a message's group **once**, and uses that one answer as the reply
address and the key for all per-group state, so the scoping gate and the
reply router cannot disagree and answer in the wrong group;
- ships a `scoping` scenario asserting that direct messages and other groups
produce zero outbound messages, run by `scripts/e2e.sh` in CI.
If you widen that boundary, the scoping scenario is what should fail.
## Secrets
`.env` is gitignored and never committed. `.env.sample` contains no real
values. The bot reads no credentials of its own: authentication is the
signal-cli data directory mounted into the container, which stays on the host.
## Reporting a vulnerability
Open an issue at https://github.com/kuhyx/signal-bot/issues. If the issue
would expose message content or account access, say so without a working
proof of concept in the public issue.
## Dependencies
Every dependency is exact-pinned at its newest stable release and checked by
`scripts/check_dependency_freshness.sh` in pre-commit and CI. There are no
pre-release pins.