Encryption, as a bot meets it
ILLEST is end-to-end encrypted. The server stores ciphertext and holds no keys, so it cannot read anything for a bot either. A bot is a member of each conversation the way a person is: with a device, a key of its own, and a place in the conversation's encrypted group. The library does all of it. What follows is what it means for the code you write.
The bot is a device
The token is enough to enrol, not to run. The first run makes the bot's keys and keeps them under ~/.illest/bots/<name>/:
| File | What it is |
|---|---|
device.json | the device key, which signs the server's challenge on every sign-in |
identity.json | the account's identity key, which vouches for the device to everybody in a conversation |
Keep that folder with the bot, and back it up the way you would a password. Losing it is losing the device and every group key only it held: the history it had read is gone, and members see the bot's security key change. A second machine running the same token is a second device.
Joining is two steps
- The invite link adds the bot to the server.
on_guild_joinfires. - The clients of people in the server let the bot's device into each channel's encrypted group, usually within seconds while
the bot is online.
on_group_join(channel)fires for each.
Until a channel has let it in, the bot cannot read or send there. A bot that has never run holds no device, so nothing can let it in at all.
What it can read
- From when it joined.
channel.history(),fetch_message()andchannel.pins()return the messages this bot holds, from when it was let into the channel's group. There is nothing older to fetch: the server cannot read it either. - While it was stopped. On start it brings every group it holds up to date before handling anything, and hands what was sent
meanwhile to
on_missed_message, withmessage.lateset, never toon_message.
Who sent it
Every message is signed by the sender's device. message.author_verified is True when the sender's own device vouched for the
account; when False, author is only the server's word, so authorise nothing on it.
import illest
from illest.ext import commands
bot = commands.Bot(command_prefix="!", intents=illest.Intents.default())
@bot.command()
async def wipe(ctx: commands.Context):
if not ctx.author_verified:
await ctx.reply("I cannot tell it is you. Try again from your own device.")
return
await ctx.channel.purge(limit=50)The library pins each account's key the first time it sees it. If an account later shows another, message.author_key_changed
is True and on_key_change(user_id) fires once. Check with the person another way, then call client.accept_key_change(user_id).
What the server does see
The server routes messages, so it knows which account sent something to which conversation, and when, and how large it was. It does not know what was said, which command was used or with what, which button was pressed, or what a form held: those travel sealed inside the conversation.
Ephemeral is a rendering rule
Every ILLEST app shows an ephemeral answer to its one reader only, but the bytes reach every device in the conversation. Inside an encrypted group nothing stronger exists. Forms and autocomplete travel the same way. Put nothing in one that the other members must not be able to read.
What a bot cannot do
A bot cannot join a voice call: calls are encrypted from each person's device, and a bot has no microphone. It sees who is in a
voice channel (on_voice_state_update) and can move or disconnect members with the moderate scope.