Documentation
¶
Overview ¶
Package oidc implements OIDC login, refresh, identity-token acquisition, and RFC 8693 token exchange.
Index ¶
- Constants
- Variables
- func Acquire(ctx context.Context, client *http.Client, source Source, clientID string) (string, error)
- func IdentityFromIDToken(idToken, usernameClaim string) (sub, email string, err error)
- func IsExpired(idToken string, skew time.Duration) bool
- func TrustedIdentity(idToken, clientID string) (sub, email string, err error)
- type Discovery
- type Source
- type SourceOptions
- type Tokens
Constants ¶
const ( ProviderGitHub = "github" ProviderBuildkite = "buildkite" )
Variables ¶
var CommandContext = exec.CommandContext
CommandContext is replaceable by tests that exercise Buildkite acquisition.
Functions ¶
func Acquire ¶ added in v0.9.0
func Acquire(ctx context.Context, client *http.Client, source Source, clientID string) (string, error)
Acquire obtains a fresh identity token. It deliberately returns redacted errors and reopens identity files on every call.
func IdentityFromIDToken ¶
IdentityFromIDToken extracts the sub claim and the configured username claim from an ID token. It does not verify the signature because the issuer already verified the token when minting it.
func IsExpired ¶
IsExpired returns true if the JWT id_token is within `skew` of expiring (or already expired). A malformed token is treated as expired.
func TrustedIdentity ¶ added in v0.9.0
TrustedIdentity validates the identity constraints Truster must enforce for an exchanged workload token.
Types ¶
type Discovery ¶
type Discovery struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
JWKSURI string `json:"jwks_uri"`
GrantTypesSupported []string `json:"grant_types_supported"`
}
Discovery is the subset of an OIDC discovery document that Podplane uses.
type Source ¶ added in v0.9.0
Source is non-secret metadata describing an upstream token source.
func SelectSource ¶ added in v0.9.0
func SelectSource(opts SourceOptions) (Source, error)
SelectSource applies explicit controls and conservative CI auto-detection.
func (Source) IsUserLogin ¶ added in v0.9.0
IsUserLogin reports whether the source requires interactive user login.
type SourceOptions ¶ added in v0.9.0
type SourceOptions struct {
IdentityProvider string
IdentityFile string
Environ func(string) string
LookPath func(string) (string, error)
}
SourceOptions controls explicit source selection. Environ and LookPath are test hooks; nil values use the process environment and exec.LookPath.
type Tokens ¶
type Tokens struct {
IDToken string `json:"id_token"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
Tokens is the result of a successful auth-code or refresh exchange.
func Exchange ¶ added in v0.9.0
func Exchange(ctx context.Context, client *http.Client, issuerURL, clientID, subjectToken string) (*Tokens, error)
Exchange performs RFC 8693 token exchange and interprets Truster's access_token as the downstream Kubernetes ID token.
func Login ¶
func Login(ctx context.Context, client *http.Client, issuerURL, clientID string, callbackPort int, headless bool) (*Tokens, error)
Login runs the OIDC authorization-code + PKCE flow and returns the resulting tokens. The caller supplies the HTTP client (it is responsible for any TLS/CA configuration the issuer needs). callbackPort 0 defaults to 8000.
In interactive mode (headless == false) the user's browser is opened to the authorize URL and we wait for the issuer to redirect back to http://localhost:<callbackPort>/callback.
In headless mode we GET the authorize URL ourselves with redirects disabled and pull the `code` straight out of the Location header. This works against any issuer that does not require interactive consent for the request — e.g. a confidential client with an existing session, an issuer configured to skip the consent screen for trusted clients, or our local fake OIDC. It is intentionally not coupled to the local provider.