Documentation
¶
Overview ¶
Package gate is AppTown access gate: a small reverse proxy that is the only public component of a restored copy of production data. The app runs behind it as an internal service. The gate lets in two kinds of caller and nobody else:
- AppTown's own probes, which carry the copy's gate secret in the AppTown-Restore-Token header;
- people AppTown has sent through /_apptown/enter with a single-use ticket, which the gate redeems with AppTown for a session cookie. AppTown's own check of the gate enters the same way, with a ticket it issued itself; the gate does not tell the two apart.
Everything else gets an empty 404, so an anonymous caller learns nothing about the app behind it. Every refusal carries the AppTown-Gate: refused header, which the gate strips from the app's own answers, so AppTown's check of the gate can tell a refusal from an app answering 404. The gate logs no request content: the copy holds production data, and paths, headers and bodies can carry it.
Index ¶
Constants ¶
const ( // TokenHeader carries the gate secret on AppTown's probes. TokenHeader = "AppTown-Restore-Token" // CookieName is the gate's session cookie. The __Host- prefix makes the // browser refuse it unless it is Secure, has Path=/ and no Domain, so // no other site or subdomain can plant or widen it. CookieName = "__Host-apptown-gate" // RefusedHeader marks the gate's own refusals (RefusedValue), so the // AppTown's check of the gate can tell a refusal from an app that answers // 404 or 403 behind a gate that let the request through. The gate // strips it from every response the app sends, so the app cannot // produce it. RefusedHeader = "AppTown-Gate" RefusedValue = "refused" // EnterPath is where a person arrives with a ticket from AppTown. EnterPath = "/_apptown/enter" // RedeemPath is AppTown endpoint that exchanges a ticket for a person // and a deadline. // It is outside /api/ on purpose: the gate presents its secret as a // bearer credential, which AppTown's API would read as a person's // token; this path authenticates the gate itself. RedeemPath = "/gate/redeem" )
const DefaultListen = ":8080"
DefaultListen is the address used when GATE_LISTEN is not set.
const TrustEnv = "APPTOWN_TRUST"
TrustEnv is the variable the extra certificates arrive in, as every container AppTown starts is given them (internal/trust.EnvVar).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
// Listen is the address the gate serves on.
Listen string
// Upstream is the app behind the gate, reached over the platform's
// internal network.
Upstream *url.URL
// Secret is the copy's gate secret: probes present it, and the gate
// presents it to AppTown when redeeming a ticket. Never logged.
Secret string
// AppTown is AppTown's public origin, where tickets are redeemed.
AppTown *url.URL
// Roots are the certificate authorities the gate trusts AppTown's
// origin by: the system's, and the extra ones in APPTOWN_TRUST, which
// is the script other containers run to install them
// (internal/trust); the gate has no shell, so it reads the
// certificates out of it. nil is the system's alone.
Roots *x509.CertPool
}
Config is what the gate needs to run. ConfigFromEnv builds it from the environment the platform gives the gate component.
func ConfigFromEnv ¶
ConfigFromEnv reads GATE_LISTEN, GATE_UPSTREAM, GATE_SECRET and GATE_APPTOWN through getenv. It refuses a missing or malformed value rather than starting a gate that would forward to the wrong place or accept a weak secret. Error messages never include the secret's value.
type Options ¶
type Options struct {
// Client redeems tickets with AppTown. The default has a 10-second
// timeout and follows no redirects, so the secret is never re-sent to a
// second address.
Client *http.Client
// Now is the gate's clock; nil is the real clock.
Now func() time.Time
}
Options are the gate's replaceable collaborators, for tests.