Skip to content

jobs/index/archive: Authenticate archive push via GitHub App#13489

Merged
Turbo87 merged 5 commits intorust-lang:mainfrom
Turbo87:archive-github-app-auth
Apr 27, 2026
Merged

jobs/index/archive: Authenticate archive push via GitHub App#13489
Turbo87 merged 5 commits intorust-lang:mainfrom
Turbo87:archive-github-app-auth

Conversation

@Turbo87
Copy link
Copy Markdown
Member

@Turbo87 Turbo87 commented Apr 24, 2026

The index SSH key used in production is a deploy key for the index repository, so it cannot push to the separate archive repository. Instead of minting a second SSH key plus user account with access to both repos, we registered a GitHub App scoped to both the index and archive repos. This job is the first consumer; the remaining index-writing jobs may switch from the deploy key to the app later.

Mints an installation access token from GH_INDEX_SYNC_APP_CLIENT_ID and GH_INDEX_SYNC_APP_PRIVATE_KEY after fetching the snapshot branch, then pushes FETCH_HEAD to the archive repository over HTTPS via a temporary archive remote carrying x-access-token credentials. For URL schemes that do not accept userinfo (e.g. file:// in tests), the job logs a warning and falls back to pushing without credentials.

Fails loudly when index_archive_url is set but no GitHub App is configured, so a misconfigured worker does not silently skip the push.

Related

@Turbo87
Copy link
Copy Markdown
Member Author

Turbo87 commented Apr 24, 2026

Note that I've tested this with https://github.com/rust-lang/staging.crates.io-index and https://github.com/rust-lang/staging.crates.io-index-archive and after an initial hickup (see below), everything worked as intended.

The hickup was this:

Failed to run job: Running git command failed with: To https://github.com/rust-lang/staging.crates.io-index-archive.git
 ! [remote rejected] FETCH_HEAD -> snapshot-2026-04-24 (refusing to allow a GitHub App to create or update workflow `.github/workflows/update-dl-url.yml` without `workflows` permission)
error: failed to push some refs to 'https://github.com/rust-lang/staging.crates.io-index-archive.git'

Apparently GitHub Apps are not allowed to push anything that changes GitHub Actions workflows, and since the index currently contained a workflow, but the archive didnt, the push failed. I've removed the workflow from the staging index and then it worked. The workflow isn't particularly helpful anymore anyway, since it only updates the config.json of the git index, but not the sparse index.

@Turbo87 Turbo87 force-pushed the archive-github-app-auth branch 2 times, most recently from 89dfb49 to 29ec4ed Compare April 24, 2026 10:10
@Turbo87 Turbo87 requested a review from a team April 24, 2026 10:10
@Turbo87 Turbo87 moved this to For next meeting in crates.io team meetings Apr 24, 2026
@Turbo87 Turbo87 force-pushed the archive-github-app-auth branch from 29ec4ed to 803015d Compare April 26, 2026 07:03
@rustbot

This comment has been minimized.

Comment thread crates/crates_io_github_app/src/test_keys.rs
Copy link
Copy Markdown
Contributor

@LawnGnome LawnGnome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread crates/crates_io_index/repo.rs Outdated
Turbo87 added 5 commits April 27, 2026 19:41
Returns a `TemporaryRemote` RAII guard that removes the registered
remote on drop. Any pre-existing remote with the same name is cleared
first so a crash in a prior job does not block setup.
New workspace crate that mints installation access tokens for a GitHub
App. Signs a short-lived RS256 JWT with the app's private key, resolves
the org's installation id once, and caches the minted access token
until shortly before expiry.

The `GitHubApp` trait abstracts the HTTP interaction for testing; a
`MockGitHubApp` is generated behind the `mock` feature. Not wired into
the rest of the workspace yet.
Adds a `github_app: Option<Box<dyn GitHubApp>>` field to `Environment`
and populates it from `background-worker.rs` startup. When
`GIT_ARCHIVE_REPO_URL` is set, both `GH_INDEX_SYNC_APP_CLIENT_ID` and
`GH_INDEX_SYNC_APP_PRIVATE_KEY` must also be present; the org is parsed
from the archive URL's first path segment and a `GitHubAppClient` is
built from those inputs. When the archive URL is unset, `github_app`
stays `None` and no credentials are required.
Adds a default `MockGitHubApp` to `TestAppBuilder` with a canned
`installation_token` expectation, plus `with_github_app` for tests
that need to override it (including clearing it via `None` to exercise
the misconfig path).
The index SSH key used in production is a deploy key for the index
repository, so it cannot push to the separate archive repository.
Instead of minting a second SSH key plus user account with access to
both repos, we registered a GitHub App scoped to both the index and
archive repos. This job is the first consumer; the remaining
index-writing jobs may switch from the deploy key to the app later.

Mints an installation access token from `env.github_app` after
fetching the snapshot branch, then pushes `FETCH_HEAD` to the archive
repository over HTTPS via a temporary `archive` remote carrying
`x-access-token` credentials. For URL schemes that do not accept
userinfo (e.g. `file://` in tests), the job logs a warning and falls
back to pushing without credentials.

Fails loudly when `index_archive_url` is set but no GitHub App is
configured, so a misconfigured worker does not silently skip the push.
@Turbo87 Turbo87 force-pushed the archive-github-app-auth branch from 803015d to 78fae34 Compare April 27, 2026 17:46
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 27, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@Turbo87 Turbo87 added the C-internal 🔧 Category: Nonessential work that would make the codebase more consistent or clear label Apr 27, 2026
@Turbo87 Turbo87 merged commit d23e9fa into rust-lang:main Apr 27, 2026
13 checks passed
@Turbo87 Turbo87 deleted the archive-github-app-auth branch April 27, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-backend ⚙️ C-internal 🔧 Category: Nonessential work that would make the codebase more consistent or clear

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants