Security model
Where the credentials live, what the model sees, and what is logged.
Credentials
API keys and tokens live in a dedicated vault. They are injected at execution time by a tool gateway. The model never sees them: not in a prompt, not in a log, not in memory.
Prompt injection
Agents are built to treat content fetched from email, web pages, documents and messages as data, not as commands. In chat, an agent asks for a human approval before it sends, changes or deletes anything critical.
Data handling
- TLS 1.2+ in transit, AES-256 at rest
- Hosted in the United States on Google Cloud, MongoDB Atlas and Supabase
- We do not train on your data, and every model provider we use is contractually barred from doing so
- Retention and deletion as set out in the Privacy Policy
Google Workspace scopes
Where you connect a Google Workspace account, Kryttle requests the scopes below. Each is listed with the feature that depends on it and why a narrower scope will not do. Scopes Google classes as restricted are covered by an annual Cloud Application Security Assessment carried out by a Google-authorised lab.
| Scope | Class | What it is for | Why nothing narrower works |
|---|---|---|---|
| openid | Non-sensitive | The stable Google account identifier, used as the key a connection’s tokens are stored against. | It returns only an identifier. Nothing narrower identifies the account at all. |
| userinfo.email | Non-sensitive | Shows you which account is connected, and detects a reconnect against the wrong account. | openid returns an identifier, not an address, so on its own it cannot show you which account you connected. |
| userinfo.profile | Non-sensitive | Name and avatar on the connections screen. | No narrower scope returns profile display data. |
| gmail.modify | Restricted | Read message bodies and attachments, send, reply, label, archive and manage drafts. | gmail.readonly cannot write. gmail.compose covers drafts and sending but cannot read. Label scopes cannot change a message’s labels, so they cannot archive. Combining them would mean requesting several scopes and still leave archiving uncovered. |
| drive | Restricted | Read any file and its contents, create and modify files, move items to the bin. | drive.file reaches only files the user has individually picked or that Kryttle itself created, which cannot satisfy an agent asked to work across an existing folder or workspace. drive.readonly cannot write, and drive.metadata returns no file contents. |
| calendar.events | Sensitive | Read, create, modify and delete individual calendar events. | Requested in preference to the full calendar scope, which would additionally grant sharing-permission management that Kryttle does not use. |
| calendar.events.freebusy | Sensitive | Check when an account, and the calendars it has access to, are free or busy, without reading event details. | calendar.events authorises reading events but not the freebusy query. The narrower calendar.freebusy covers only the account’s own calendars, not the shared ones an agent needs when scheduling across a team. |
| calendar.calendarlist.readonly | Sensitive | List the calendars an account is subscribed to, so you can choose which one an agent acts on. | calendar.events cannot list calendars. The full calendar scope can, but also grants sharing-permission management Kryttle does not use. |
The Sheets, Docs, Slides and Forms APIs all accept the drive scope, so Kryttle requests no separate spreadsheets, documents, presentations or forms scope. Cell-range operations, structured document editing, and reading a form and its responses are all authorised by drive alone. Kryttle does not request the full calendar scope. Our commitments under the Google API Services User Data Policy, including the Limited Use requirements, are set out in the Privacy Policy.
Security testing
The application is tested with static and dynamic application security testing, using Fluid Attacks and OWASP ZAP.
Audit
Every action is logged: who acted, what they did, when, and from where.