Approved senders for message channels (who can auto-start a session)
A per-channel allowlist of who is allowed to auto-start paid work — a session, a reply to the sender, or a workflow — from an inbound text, Slack message, or Telegram message. An unapproved sender still reaches your inbox and still runs your free rules; only the paid parts are gated, and an empty list means nobody.
What it is
Omniscio can automatically start an AI session or run an automation when a message arrives on a connected messaging channel — a text (SMS), a Slack message, or a Telegram message. That's powerful, but it means whoever can message you could, in principle, kick off a paid AI session (via an automation you set up or a workflow trigger).
The Approved senders list closes that gap. For each of these three channels you keep a small allowlist of who is allowed to auto-start work:
- SMS — phone numbers
- Slack — Slack user IDs
- Telegram — Telegram sender IDs / usernames
An inbound message from an unapproved sender still runs your free rules — archiving spam, forwarding a code to your email, showing a notification, an AI spam-check — and still arrives in your inbox as normal. What an unapproved sender cannot do is drive the paid parts: auto-starting or continuing an AI (Claude) session, auto-replying a text straight back to the sender, or firing a workflow. Only a sender on that channel's list can do those.
Where to find it
Settings → Connections → Channels → open SMS, Slack, or Telegram. When the channel is turned on, an Approved senders card appears. It shows:
- the people currently allowed (as removable chips), and
- an Add box to type a new phone number / ID.
When the list is empty the card explains that no one can auto-start a session yet and invites you to add senders you trust.
How it behaves
The most important rule: empty means nobody
The list is fail-closed: if a channel's Approved senders list is empty, nobody can auto-start a session on that channel. This is on by default and deliberate — so an unknown texter or a stranger in a Slack channel can never spin up a paid AI run before you've said who you trust. To let a sender through, you add them to the list.
This is the opposite of the older Email Inbound "Approved Senders" box, where an empty list means "allow anyone" (because email intake has a separate secret-token gate). For SMS/Slack/Telegram there is no such token, so empty = allow no one.
How you'll know it's working (the heads-up note)
Because "empty = nobody," turning this on can pause an inbound auto-start you were relying on. So you're never left guessing: the first time a message from an unapproved sender actually would have started a paid session, reply, or workflow — and only if you have automations turned on — Omniscio drops one note in your Inbox, e.g. "An SMS message was blocked from starting a session because the sender isn't on your approved-senders list." It names an example sender so you can copy the ID straight into the Approved senders box if you trust them. You get one note per channel, not one per message, so it never floods your Inbox.
Note: if an unapproved sender's message only triggered your free rules (a spam-archive, a code-forward), nothing paid was blocked — so no note appears, and those rules simply run.
What it does NOT do
- It does not hide or delete messages, and it does not disable your free rules. A blocked sender's message still shows up in your inbox, and your free automations (archive / forward / notify / AI spam-check) still run — only the paid parts (an AI session spawn, an auto-reply to the sender, or a workflow) are gated.
- It is not a security wall. A sender's phone number / Slack ID can be spoofed, so treat the list as a convenience-and-cost guard (stop surprise paid runs), not as authentication.
- It does not affect email (that has its own Approved Senders + prescreen), nor read-only channels like RSS, nor webhooks (which use their own secret token).
For agents
Under the hood
- The gate lives at the one place every inbound message passes through:
dispatchInboundMessageinsrc/main/services/automation/legacy/dispatch-inbound-message.ts. For an unapproved sender on a gated channel it does NOT return early — it runs both legs with the paid work suppressed:processMessage(msg, { paidActionsAllowed: false })andevaluateMessageWorkflows(msg, { paidSpawnAllowed: false }). Free actions + AI conditions run; only the sender-gated actions and workflow runs are skipped. - The gated ACTIONS are a shared constant,
SENDER_GATED_ACTION_TYPESinsrc/shared/message-sender-gate.ts(cli_session,cli_send_to_session,auto_respond— a paid session spawn or a reply to the sender). The legacyexecuteActionskips them whenctx.paidActionsAllowed === false; every other action runs. The blocked-sender note fires only when one of these — or a matched workflow — was actually suppressed. - The decision is a pure function,
isMessageSenderAllowed(src/main/services/automation/legacy/message-sender-policy.ts): empty list → deny; SMS numbers are compared in canonical E.164 form, other IDs case-insensitively. - The gated channel list is shared (
src/shared/message-sender-gate.ts,SENDER_GATED_CHANNELS = ['sms','slack','telegram']) so the enforcement and the Settings UI never drift. - The setting is
messageInboundApprovedSenders(a per-channel map) insrc/shared/types/settings/channels-settings.ts. - Full invariants + rationale:
.claude/memory/contracts/inbound-sender-allowlist-contract.md.
This closed the security-sweep findings (inbound SMS/Slack/Telegram messages and workflow message-triggers reaching a billable spawn with no sender allowlist).
Related
Email intake is a separate system with its own sender list, described on the Email inbound prescreen page. The inbox a blocked sender's message still lands in is the Inbox overview, and the automations a message can trigger are on the Automations and auto-replies page.
Last verified 2026-09-28