Repository Sync Guide

Diagrams from a private repository: exact scopes, and what leaves the repo

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

Pointing a third-party tool at a private repository is a security question before it is a diagramming question, and the honest version of the answer is a list: which scope, stored how, used against which endpoints, revoked how. This page is that list, per provider, plus the parts that are worth knowing before the security review asks.

7 min readFor the person who has to justify the integration, not just click connect

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

132/20003 credits left
Try:

No account needed · Editable canvas, not a picture

The exact scope, per provider

GitHub: a fine-grained personal access token scoped to the single repository, with the repository permission Contents set to Read-only. GitHub adds Metadata Read-only automatically, and that pair is the entire requirement. A classic token with the repo scope also works but carries write access, so it is the worse choice for a read-only integration.

GitLab: a personal access token with the read_api scope. That is what covers listing branches and tags, listing the repository tree, and reading raw file contents on gitlab.com.

Azure DevOps: a personal access token with Code set to Read, documented by Microsoft as vso.code, for the organization that owns the project. It is presented as basic authentication with an empty username, which is the shape the API expects.

Public repositories on all three hosts need no token at all. The connection simply reads what anyone can read.

Provider       Scope                          Public repo
  github         Contents: Read-only            no token
                 (fine-grained, one repo)
  gitlab         read_api                       no token
  azure_devops   Code: Read                     no token

What happens to the token after you paste it

It is validated immediately, by listing the branches and tags of the repository. That is the cheapest call that proves both that the credential works and that it can see this specific repo, so a wrong scope fails at connect time instead of failing silently at the first sync three hours later.

It is then encrypted at rest with AES-256-GCM under a key derived by HKDF-SHA256 with an info string reserved for repository tokens, so it is not the key that protects the rest of the application secrets. The stored blob is base64 of a 12-byte random initialization vector, the ciphertext, and the 16-byte GCM authentication tag, which means a tampered or wrong-key value fails loudly at decrypt instead of yielding bytes that would then be sent to a provider as a header. Only the last four characters ever come back to the interface, and error messages are built from URL paths and HTTP status codes alone, so a token cannot end up quoted in a log line or an API response.

Every other stored credential in the product is a one-way SHA-256 hash. Provider tokens are the exception because they have to be replayed to GitHub, GitLab, or Azure DevOps on every fetch, which is exactly why they get their own key derivation rather than riding along with the rest.

Deleting a connection removes the stored token and all of the diagrams linked through it, while every project survives with its last synced content. Rotating is the same shape: revoke at the provider, create a fresh token with the same scope, and reconnect.

It never writes

Every provider call the sync makes is a read: list refs, list tree, read file. There is no code path that commits, opens a merge request, or posts a status. The repository sync documentation lists the endpoints per provider.

What actually leaves the repository

Not the whole repo. The reading step selects up to 40 files and 250KB in total, in priority order: infrastructure as code, containers and orchestration, data definitions, API specs, CI pipelines, dependency manifests, then prose. Each class carries its own ceiling on top of that, 12 infrastructure files, 12 deployment manifests, 10 API definitions, 8 CI pipelines, 8 dependency manifests and so on, so no one class can spend the whole budget. Files past 30KB are truncated with a visible marker and anything over 400KB is skipped outright. Lockfiles are dropped by name, and node_modules, vendor, dist, build, .next, target, .terraform, coverage, __pycache__ and virtual environment directories are never walked.

What comes back is a diagram and an architecture.md grounded in those files. The generated doc is instructed to state that a section is unanswered rather than fill it in, which is what makes it reviewable against the repo it came from.

There is also a path where nothing leaves the repository at all. Over MCP, your coding agent reads the code locally and sends only the structure it chose to draw, node names, zones, and edges, because no tool in the server accepts source files. Teams that cannot connect a repository at all often run that path instead, and the two land on the same canvas.

The two failure states, and what each one means

A connection that turns to auth_failed means the provider rejected the credential: revoked, expired, or missing the read scope. The fix is a fresh token with the exact scope above, entered on the connection.

A connection that turns to not_found means the provider says no such repository exists for this token. On GitHub that is usually a fine-grained token that was not granted access to this particular repository, since fine-grained tokens list their repositories explicitly. It also covers a renamed repo, a deleted one, and the case where a public repo went private while the connection had no token at all.

Neither state touches the existing diagram. A failed sync leaves the previous canvas exactly as it was, and the error is shown with the link so the reason is visible next to the thing that stopped updating.

FAQ

What is the minimum GitHub permission needed to diagram a private repo?

A fine-grained personal access token scoped to that one repository, with the repository permission Contents set to Read-only. GitHub attaches Metadata Read-only automatically, and that pair is the entire requirement. A classic token carrying the repo scope also works, but that scope includes write access, so it is the weaker choice for an integration whose every call is a read.

Is my source code stored?

The sync reads a bounded selection, up to 40 files and 250KB, to generate the diagram and the architecture doc. Files over 30KB are truncated with a marker, and lockfiles, binaries, and vendored directories are never read. The generated artifacts are what persist with the project.

How is the access token protected at rest?

It is encrypted with AES-256-GCM using a fresh initialization vector per token and a key derived specifically for repository tokens. Only the last four characters are displayed again, and tokens never appear in logs, API responses, or error messages, which are built from URL paths and HTTP status codes.

What happens if I revoke the token at the provider?

The next sync fails and the connection moves to an auth_failed state, with the reason shown next to the link rather than buried in a log. The existing diagram and its architecture doc are untouched, and any live embed of it keeps serving the last good version. Entering a fresh token with the same read scope restores syncing from the next run.

Can I get a diagram without connecting the repository at all?

Yes. A coding agent connected over MCP reads the code on your machine and calls canvas tools with only the structure it decided to draw, since no tool accepts source files. That path leaves the repository where it is, at the cost of updating only when someone runs a session.

Does deleting the connection delete my diagrams?

It deletes the stored token and the links, but every project survives with the content of its last sync, canvas and architecture doc included. Unlinking a single diagram is the narrower version of the same move: the project keeps everything it has and simply stops syncing, which is the right end state for a branch diagram whose branch has merged.