# What access gitdr asks for, and why

The exact scopes on each side, why backup never needs write, and why restore doesn't either.

A backup run holds two credentials, one for your git host and one for your bucket.
Neither can write to your code, your CI, or an existing backup. This page lists the
exact grants, so you can check every one against the
[code](https://github.com/gitdr-io/gitdr), which is open.

## The source credential (read-only)

The credential gitdr backs up with cannot write.

**GitHub.** gitdr authenticates as a GitHub App installation. The App needs four
repository permissions, every one of them read:

```
contents        read-only    the git data itself, plus releases
metadata        read-only    lists the org's repos, mandatory for any App
issues          read-only    issues, comments, labels, milestones
pull requests   read-only    pull requests and review comments
```

That is the whole set. A token minted from it can't push a commit, edit a workflow
file, or change a setting. Same grants on GitHub Enterprise Server.

**GitLab.** A project or group access token with two scopes, `read_api` and
`read_repository`. The first reads metadata over the API, the second pulls the git
data. Both are read scopes by GitLab's own definition. Same on self-managed GitLab.

Where the secrets go (env only, never in the YAML) is on the
[configuration page](/docs/configuration/).

## Why backup never needs write

A backup is a read. Cloning a mirror, listing repositories, and paging through issues
modify nothing, so a write scope would have no job to do. The binary couldn't use one
anyway. The Source interface has three methods, `ListRepos`, `CloneURL`, and
`FetchMetadata`, and no method mutates the upstream VCS. Hand gitdr a broader token
than it asked for and the extra grants sit unused, there is no code path that writes
to a source.

## Restore (credentials supplied at restore time)

Restore uses the same open-source binary with read access to the bucket. It downloads
the bundle, re-checks the checksum, and clones into a local directory. It never writes
to the destination.

Pushing the restored repo to a new home is a `git push --mirror` with a credential you
create at that moment, on whichever host you are restoring to. gitdr never holds it in
advance. So no standing write access to your code or CI exists anywhere in gitdr,
nothing sits in a vault between runs, and nothing is there to steal. The
[restore runbook](/docs/restore/) walks the whole path.

## The destination credential (create and put)

Backup needs create/put on the bucket. `verify` and `restore` need read. Nothing ever
needs delete, so don't grant it.

The code is built to match. The storage interface has no delete, remove, or overwrite
method anywhere in the codebase, enforced by lint in CI. Uploads are create-only, so a
key collision fails instead of replacing the object. Scope the credential the same way
and a leaked one can add objects to your bucket, and that is all it can do.

## Immutability is verified, never asserted

Before writing anything, gitdr asks the storage API whether the bucket is locked, the
S3 Object Lock configuration, the GCS retention policy, the Azure immutability policy.
A confirmed lock is recorded in the signed manifest. No confirmed lock means a loud
warning while the run proceeds, or a hard stop with `--require-worm`. gitdr never
reports protection it did not verify. [WORM buckets](/docs/worm/) shows how to set one
up per provider.

## Compare

The next time a backup tool asks you to authorize it, put its consent screen next to
this page.