Channel Janitor — Privacy Policy

Last updated: 30 July 2026. Applies to the Channel Janitor Slack app.

The short version

Channel Janitor scans your Slack workspace’s public channels for staleness — channels with no human activity past a threshold you configure (90 days by default) — sends a review queue of candidate channels to a Telegram chat, and archives only the channels you approve. Every action is written to an append-only audit log. To decide whether a channel is stale the app reads channel history, but the only thing it keeps from that history is a timestamp: message text is never stored. The app does not sell or share your data, and it contains no advertising or cross-site tracking.

What data the app collects and stores

The app’s own database holds four tables, and nothing else:

TableContents
Installation Your Slack workspace (team) ID and workspace name, the Slack bot OAuth token (encrypted at rest with AES-256-GCM — see src/crypto.js), the bot user ID, the Slack user ID of the person who installed the app, the OAuth scopes granted at install, your staleness threshold in days, the plan (free / pro), the Stripe customer and subscription IDs (only once Stripe billing is configured), the Telegram chat ID that receives your review queue, and install/update timestamps.
ChannelCandidate Per candidate channel: the channel ID and name, the timestamp of the last human activity, the computed days-stale, the member count, the decision status (pending / skipped / archived / error), the Telegram chat and message IDs of the review card, and when it was proposed and decided.
AuditLog Append-only: the action (install, scan, proposed, approved, skipped, archived, error, billing, uninstall), the channel ID and name it concerned, a short free-text detail string (for example 212d stale), and a timestamp.
LinkToken A random single-use token, the workspace ID it is bound to, its expiry (15 minutes after issue), when it was redeemed, and when it was created. Created by /janitor link so that a Telegram chat can prove which workspace it belongs to. It contains no channel data and no message content. See the retention section for how long these rows live.

What the app does not store

Which Slack permissions the app asks for, and why

ScopeUsed for
channels:readlist the workspace’s public channels
channels:historyread a channel’s history to find the timestamp of the last human message
channels:joinjoin a public channel, which Slack requires before its history can be read or it can be archived
channels:managearchive a channel you approved
chat:writepost messages in Slack
commandsreceive the `/janitor` slash command
team:readread the workspace name shown on the review cards

This is the complete list the install URL requests. Reading channel history requires the app to be a member of the channel, which is why channels:join is included; #general is deliberately never joined and never scanned.

Where the data is stored

The app’s data lives in a self-hosted PostgreSQL 16 instance running in its own container on our own server. That container is attached only to a private Docker network shared with the app; it is not published to the internet, and the single host port it exposes is bound to 127.0.0.1 for maintenance from the server itself. The Slack bot token is additionally encrypted at the application level with AES-256-GCM before it is written, so a database file on its own does not yield a usable token.

Server and container logs

Besides the database, the app writes operational log lines that the server keeps for debugging. These contain:

Logs are rotated by size rather than kept for a fixed period, so older lines are discarded as new output arrives. They are readable only by us, on the server, and are not shared with anyone.

Data retention and deletion

When you uninstall the app, Slack sends an app_uninstalled event and the app deletes your Installation row. That deletion cascades, so every ChannelCandidate, AuditLog and LinkToken row for your workspace is deleted with it. All four tables named above are covered; nothing about your workspace is kept behind. The cascade is enforced by the database itself through foreign keys, not by application code that could be skipped.

One scheduled clean-up, stated plainly: while your workspace is still installed, a daily job deletes LinkToken rows whose 15-minute validity expired more than a day ago. These are the one-time connect links produced by /janitor link; once expired they cannot be redeemed, so removing them costs you nothing. Tokens that are still valid are never touched by that job, and it never touches any other table.

There is no other automatic expiry or scheduled purge in the app: candidate channels and audit-log entries are kept for as long as your workspace has the app installed, and are deleted when you uninstall. Channels you archived while using the app stay archived in Slack — that is a change to your workspace, not data we hold.

Data sharing

The app does not sell, rent, or share your data with third parties for their own purposes. Data is exchanged only with the following providers, strictly to operate the app:

Your rights under the GDPR

If you are located in the European Economic Area, you have the right to access, rectify or erase the personal data held about you, to restrict or object to its processing, and to data portability. You can exercise these rights by contacting us at the address below, or by uninstalling the app — which deletes your workspace’s data in full, as described under “Data retention and deletion”.

Security

Communication with Slack, Telegram and Stripe uses HTTPS. The app authenticates to your workspace with a Slack OAuth token rather than a password, and that token is encrypted with AES-256-GCM before storage. Every inbound Slack request is verified against Slack’s request signature before it is acted on, and every Stripe webhook is verified against Stripe’s signature. Approve and skip actions are accepted only from the Telegram chat linked to your workspace.

Changes to this policy

If this policy changes, the updated version is published on this page with a new “last updated” date.

Contact

Questions about this policy: info@kyc-checks.nl.