Skip to main content

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;