Documentation
¶
Overview ¶
Package auth applies an integration's credentials to an outbound HTTP request. It is the pluggable authentication half of the integration framework: a Config (plain data, part of an integration spec) selects a Provider, and every surface that calls a remote API (the API tool, the scraper) authenticates the same way, by calling Apply before handing the request to the shared request transport.
Credentials are never written into a spec. A Config names the auth scheme and the vault references to resolve, and Apply looks each reference up through a secret.Source (the vault boundary) at call time. The resolved value is a secret.Text and is exposed exactly once, at the single point where it is written onto the request, so a credential never lands in a logged config, an event, or the spec itself.
Apply is defensive about the data it writes. The header name and value it produces are validated against the HTTP grammar before they are set, so a hostile or malformed credential, prefix, or parameter name cannot smuggle CR/LF and inject a second header. Query-placed keys go through url.Values, which percent-encodes them, so the same injection is structurally impossible there.
Index ¶
Constants ¶
const ( // GrantClientCredentials authenticates with the client's own credentials, for // server-to-server access. GrantClientCredentials = "client_credentials" // GrantRefreshToken exchanges a stored refresh token for an access token. GrantRefreshToken = "refresh_token" )
OAuth2 grant types.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
Type Scheme `json:"type,omitempty"`
// TokenRef is the vault reference for the credential used by SchemeBearer and
// SchemeAPIKey.
TokenRef string `json:"token_ref,omitempty"`
// UsernameRef and PasswordRef are the vault references for SchemeBasic. Either
// may be empty (an empty username or password is sent), but not both: a basic
// config that resolves nothing is an error.
UsernameRef string `json:"username_ref,omitempty"`
PasswordRef string `json:"password_ref,omitempty"`
// In selects header or query placement for SchemeAPIKey. Empty means InHeader.
In Placement `json:"in,omitempty"`
// Param is the header or query-parameter name for SchemeAPIKey (e.g.
// "X-API-Key", "api_key"). Required for SchemeAPIKey.
Param string `json:"param,omitempty"`
// Prefix is an optional literal prepended to the SchemeAPIKey value (e.g.
// "Token ", "Bearer "). It is part of the wire value, not a secret.
Prefix string `json:"prefix,omitempty"`
// OAuth2 fields (SchemeOAuth2). TokenURL is the token endpoint. ClientID is the
// client identifier (semi-public, carried inline); ClientSecretRef and
// RefreshTokenRef are vault references for the client secret and a refresh token.
// Grant selects the flow ("client_credentials" by default, or "refresh_token");
// Scopes are requested at the token endpoint. A token endpoint returning an
// access token and its lifetime is all this needs: the access token is cached and
// refreshed, and never stored in a spec.
TokenURL string `json:"token_url,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecretRef string `json:"client_secret_ref,omitempty"`
RefreshTokenRef string `json:"refresh_token_ref,omitempty"`
Grant string `json:"grant,omitempty"`
Scopes []string `json:"scopes,omitempty"`
}
Config is the data form of an integration's auth: the scheme plus the vault references and placement it needs. It carries no secret values, only the names to resolve them by, so it is safe to serialize, log, and store in a spec. The zero Config is SchemeNone (apply nothing).
type Option ¶
type Option func(*options)
Option configures FromConfig.
func WithClock ¶
WithClock supplies the clock SchemeOAuth2 measures token expiry against (default clock.System). Tests pass a manual clock for determinism.
func WithTokenExchanger ¶
func WithTokenExchanger(e TokenExchanger) Option
WithTokenExchanger supplies the transport SchemeOAuth2 uses to call the token endpoint. It is required to build an oauth2 provider.
type Provider ¶
type Provider interface {
// Apply resolves the credentials this provider needs from src and writes them
// onto req. A missing credential (secret.ErrNotFound) is a terminal fault: the
// integration is configured to need it and cannot proceed without it. Apply
// never writes a header it could not validate.
Apply(ctx context.Context, req *http.Request, src secret.Source) error
// Scheme reports the mechanism this provider implements, for audit and
// introspection.
Scheme() Scheme
}
Provider applies a single auth scheme to a request. It is the pluggable unit of the framework: FromConfig builds one from a Config, and a surface calls Apply on every outbound request before dispatching it through the transport.
func FromConfig ¶
FromConfig builds the Provider a Config selects, validating that the config carries the references its scheme requires. An unknown scheme, or a scheme missing a required field, is a terminal configuration fault. The zero Config and SchemeNone both yield the no-op provider. SchemeOAuth2 requires a TokenExchanger (see WithTokenExchanger); the other schemes ignore the options.
type Scheme ¶
type Scheme string
Scheme names an authentication mechanism. It is the discriminant of a Config: the value an integration spec carries to say how its requests are signed.
const ( // SchemeNone applies no credentials. It is the explicit "public API" choice, // distinct from an unset scheme, and the zero value. SchemeNone Scheme = "none" // SchemeBasic sends RFC 7617 HTTP Basic credentials in the Authorization header. SchemeBasic Scheme = "basic" // SchemeBearer sends a token as "Authorization: Bearer <token>". SchemeBearer Scheme = "bearer" // SchemeAPIKey sends a key in a named header or query parameter, with an // optional value prefix. SchemeAPIKey Scheme = "api_key" // SchemeOAuth2 obtains a short-lived access token from a token endpoint and sends // it as a bearer token, refreshing it when it expires. SchemeOAuth2 Scheme = "oauth2" )
type TokenExchanger ¶
type TokenExchanger interface {
Do(ctx context.Context, req *http.Request) (*http.Response, error)
}
TokenExchanger performs the token-endpoint request for SchemeOAuth2. The shared request transport satisfies it, so a token request is dispatched through the same governed path (anti-SSRF dialer, bounded retries) as every other request.