An issue thread holds what nobody has reread
A code repository does not only hold code. Its issues carry execution traces pasted in exactly as they were, with a client's name inside. Its reviews carry the discussion of a vulnerability before it was fixed. Its comments sometimes carry a token someone pasted to help a colleague reproduce a bug.
An AI plugged into that material becomes genuinely useful to your engineering teams. It also becomes the shortest path for a sentence written in a repository to surface in front of someone who never had access to that repository. The connector handles that risk by reducing what it reads and hardening what it opens.
What a repository holds, and what your Kastel does with it
The connector only ever asks for a repository's issue list, an issue's comments, and the repository's access permissions. The exclusions below are therefore not a filter applied after reading.
| In your GitHub repository | What your Kastel does with it |
|---|---|
| An issue's title and body | Read |
| An issue's comments, code reviews included | Read |
| A pull request, its title and its body | Read, a pull request is handled as an issue |
| An issue closed three years ago | Read, issues are requested in every state |
| A pull request's diff | Never requested |
| The code in the repository's files | Never requested |
| The repository's README and wiki | Never requested |
| Labels, assignees and the milestone | Returned by GitHub, never written |
Code stays out for two reasons. A secret left behind in a file then has no path into your Kastel. And code answers no management question, whereas the discussion around it often does.
The right to read is computed on the repository
GitHub sets no permission on an issue. An issue has no audience of its own, it inherits its repository's, and the same is true of a pull request. So the connector goes and fetches the repository's access. That is a fundamental difference with a Jira issue, which can carry its own security level, and the difference comes from the tool rather than from us.
That access is made of two lists. The collaborators added directly to the repository, and the teams with access to it, each team expanded into people. The union of the two has to belong to a single department for the repository's issues to be readable by that department. Two departments in the union, a team that cannot be expanded, a person with no address your organisation can resolve, and the repository's issues are filed nowhere.
Every list is walked to the end. When a page announces more to come without giving the means to reach it, the connector refuses to conclude from a partial list, and it refuses in the same way when it enumerates your repositories. A partial enumeration would suggest that the unread issues had disappeared, which is the quietest way to lose data.
A repository with issues disabled is skipped without failing the pass, and a repository the token can no longer read does not bring the others down. The rest of the account keeps being read.
A public repository is the strictest case
Intuition says a public repository poses no problem, since the whole world can already see it. The connector does the opposite of that intuition. A public repository goes straight on hold, and its collaborators are not even consulted.
The reason lies in what the connector is trying to reproduce. It does not classify content by how sensitive it is, it reproduces the audience of the source. A private repository has a finite audience, which can be reduced to people and then to a department. A public repository has no finite audience, so there is nothing to reproduce, and the connector stops there.
The fact that anyone can read an issue thread does not make it harmless inside your Kastel. Filed in there, it stops being a page someone might find and becomes an answer given with your company's authority, to whoever asks a plugged-in AI. An administrator can decide to open that repository to a department, and that decision is taken and recorded. The connector does not take it on their behalf, which is the difference between adjusting an access and governing it.
Issues and reviews, never the code
Two lists, one for the content written into your Kastel, the other for what the connector never asks GitHub for.
Collaborators and teams are read as a permission rule, never as content. They serve to work out who may read the repository's issues, and their names do not appear in what an AI receives.
What this connector does not do
It does not work inside GitHub. No issue is opened, commented on or closed, no pull request is reviewed or merged. The transport it uses only knows how to read, and the token travels in the header, never in an address.
Nothing sorts an issue by its content. A token pasted into a comment comes in with the comment, an execution trace naming people comes in with the bug report that holds it. A comment's text is in fact kept without its author, so a plugged-in AI will not be able to tell you who wrote the sentence it quotes to you.
An access change is not seen straight away. GitHub does not change an issue's date when a team gains or loses a repository, and it emits no per-issue signal for that kind of change. A reconciliation pass recomputes the access of every tracked repository and refiles its issues, and until then a reshared repository keeps the filing it had.
An issue deleted on GitHub is not erased from your Kastel. Your Kastel keeps the issue while noting its disappearance at the source, changing nothing about who can read it, until an administrator decides to erase it. That behaviour is shared by every Kastel connector. A repository that leaves the token's reach is not even touched, because nothing proves its issues were deleted.
Connect a private repository and look at what an AI gets.
The core of Kastel is free to self-host, with all of its connectors. The pricing page says what that core holds, what the paid plans add on top, and from what point a plan becomes necessary.
See pricing