Documentation
¶
Overview ¶
Package forgehost decides which forge host a repository reference names, and whether two references name the same one (Task 20423).
Why one helper ¶
A brokered GitHub credential is good against exactly one forge: github.com for a personal access token, unless the secret recorded a GitHub Enterprise Server host, and the web host of its base_url for a GitHub App. Every place that chooses or binds such a credential — the hub's grant picker, workspace provisioning, the git proxy's sessions, a feature's push and pull request — has to compare the host a project's origin names against that one. They used to compare nothing at all: a repository was "owner/name", the host was thrown away, and a project whose origin named https://attacker.example/acme/tool matched a grant for acme/* and had the token sent there.
The comparison is easy to get subtly wrong in ways that matter in only one direction. Folding too little refuses a working configuration (GitHub.com vs github.com); folding too much — matching suffixes, ignoring a non-default port, comparing Unicode by eye — hands the credential to a host nobody granted. So there is one definition, here, and every caller uses it.
What is folded, and what is not ¶
Folded, because both spellings reach the same server: letter case, a trailing dot, userinfo, the scheme's default port (443 for https), and an internationalised name's Unicode spelling (compared in its IDNA ASCII form, so a full-width "github.com" is github.com).
Not folded, because the two spellings reach different servers: any other port, any other label, and a Unicode look-alike — "gіthub.com" with a Cyrillic "і" is xn--gthub-n2e.com, which is somebody else's domain. There is no suffix or wildcard matching of any kind: github.com.attacker.example and attacker-github.com are simply other hosts.
Index ¶
Constants ¶
const GitHub = "github.com"
GitHub is the public GitHub's web host: where a github_pat with no recorded host, and an App on the public API, may be presented.
const GitHubAPI = "https://api.github.com"
GitHubAPI is the public GitHub's REST API base.
Variables ¶
var ErrInvalid = errors.New("forgehost: not a usable forge host")
ErrInvalid reports a reference that names no usable forge host. A caller treats it as a host that matches nothing: a credential is never presented to something this package could not identify.
Functions ¶
func APIBase ¶
APIBase returns the REST API base for a GitHub web host: the public API for github.com, and GitHub Enterprise Server's /api/v3 otherwise.
func Canonical ¶
Canonical returns the host raw names in the form two references to one forge host compare equal in: lower case, IDNA ASCII, no trailing dot, no userinfo, and a port only when it is not the scheme's default.
raw may be a bare host ("GitHub.com."), a host and port ("ghes:8443"), an authority with userinfo ("git@github.com"), or a URL whose host is wanted ("https://user@GitHub.com:443/acme/tool"). A bare host or authority is read as https. An scp-like remote ("git@github.com:acme/tool") is not a host: its caller splits the host off first.
func Check ¶
Check reports a *Mismatch when origin and grant name different hosts, and nil when they name the same one. An origin that names no usable host is a mismatch too, with the raw text in Origin.
func Equal ¶
Equal reports whether a and b name the same forge host. A reference either side cannot canonicalise names no host, so it is equal to nothing — not even to itself.
func WebHostForAPI ¶
WebHostForAPI returns the web host a GitHub App's API base serves: the host a token minted through it is good against.
https://api.github.com → github.com https://ghes.example.com/api/v3 → ghes.example.com (GitHub Enterprise Server) https://api.acme.ghe.com → acme.ghe.com (GitHub Enterprise Cloud with data residency)
Any other base — one that names neither an /api/v3 path nor an api. host — is not where GitHub Enterprise Server serves its API, so it is read as standing in for the public API: a corporate proxy in front of api.github.com, or a test's fake. Its tokens are github.com tokens, and are bound there.
Types ¶
type Mismatch ¶
type Mismatch struct {
// Origin is the host the repository reference names.
Origin string
// Grant is the host the credential is good against.
Grant string
}
Mismatch describes a credential refused because the host a reference names is not the one its grant is good against. Both are in canonical form.