vgi_forge_github/lib.rs
1//! GitHub adapter for VGI git namespaces.
2//!
3//! Implements [`vgi_forge::Forge`] for github.com and GitHub Enterprise
4//! Server, acting as **one community's own GitHub App** (§5.7 of the design:
5//! no shared operator, one App and one bridge per community).
6//!
7//! - **Auth.** The App key signs a nine-minute RS256 JWT
8//! ([`jwt::app_jwt`]) through an [`AppKeySigner`] — in-process
9//! ([`InProcessKey`]) or an enclave. Every operation then mints its own
10//! installation token, scoped to the one repository and the permissions
11//! that operation needs, and drops it on return. Nothing long-lived is
12//! cached.
13//! - **Registration.** [`manifest`] builds the App manifest with the fixed,
14//! reviewed permission set and exchanges GitHub's code for the App's
15//! credentials ([`manifest::AppCredentials`], zeroized, never printed).
16//! - **Binding.** [`vgi_forge::Forge::begin_bind`] sends the admin to the
17//! App's install page with a `state` nonce; `complete_bind` checks it in
18//! constant time and confirms the installation is this App's, on the
19//! expected owner.
20//! - **Accounts.** Members link through the OAuth device flow; the bridge
21//! keeps the numeric id and login and discards the user token.
22//! - **Repos.** Create (organisations only — a personal account reports
23//! `bot_can_create_repos: false`, §8), inspect, archive, converge roles,
24//! and the §5.3 bootstrap with a ruleset that has no bypass actors. So that
25//! a pull request cannot satisfy its own check (§9), an organisation with
26//! org rulesets runs verify-trust as a **required workflow** from the
27//! bridge-managed `<org>/.vgi` at a pinned commit; elsewhere the workflow
28//! is committed to the repository and, with two or more owners, guarded
29//! by `CODEOWNERS` plus code-owner review; a solo repository gets the
30//! check alone ([`plan::CheckGuard`]).
31//! - **Webhooks.** `X-Hub-Signature-256` verified in constant time before
32//! parsing; repository, member, membership, ruleset and installation
33//! events become [`vgi_forge::ForgeEvent`]s.
34//! - **Bridge-posted checks.** With [`GitHubConfig::bridge_checks`], a
35//! namespace without an org required workflow gets no workflow at all:
36//! the bridge runs verify-trust on each pull request and posts the check
37//! as the App ([`checks`]), and the ruleset requires it from the App's own
38//! integration id, which no workflow can post as (§9).
39//! - **Dependabot re-sign.** `push` deliveries (who moved which branch) and
40//! a per-repository push token, for the bridge to re-sign Dependabot pull
41//! requests with its own DID on signed provenance ([`resign`]).
42//!
43//! The HTTP layer is a thin reqwest client ([`api`]) rather than octocrab:
44//! see the crate README for why.
45
46mod api;
47pub mod checks;
48mod config;
49mod forge;
50pub mod jwt;
51pub mod manifest;
52pub mod plan;
53pub mod resign;
54mod secret;
55pub mod webhook;
56
57pub use api::API_VERSION;
58pub use checks::{CheckConclusion, CheckTrigger, CheckTriggerKind, Comparison, PullRequestInfo};
59pub use config::{DEFAULT_CHECKOUT_ACTION, GitHubConfig, JwtIssuer};
60pub use forge::{GitHubForge, RequiredWorkflowPin};
61pub use jwt::{AppKeySigner, InProcessKey};
62pub use resign::PushEvent;
63pub use secret::Secret;