oauthrefresh

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package oauthrefresh is the RFC 6749 refresh-token grant, spelled once for the two places that perform it: the control plane's mcp_oauth_validate probe and the executor's dial-time credential resolution.

It builds the request and reads the grant, and stops there. The HTTP client, the response capture and what a failure means all belong to the caller, because they genuinely differ — the probe dials through an SSRF-guarded client and renders a scrubbed copy of whatever came back, while a dial-time refresh captures nothing and needs only the token. What must not differ is the wire: which fields a grant carries, which of the three client-authentication arms puts the secret where, and how the Basic arm escapes it.

Index

Constants

View Source
const (
	AuthNone  = "none"
	AuthBasic = "client_secret_basic"
	AuthPost  = "client_secret_post"
)

The token_endpoint_auth arms the reference admits. Anything else is treated as a public client: sending the secret to an arm this platform does not understand is the one outcome worse than not sending it.

Variables

This section is empty.

Functions

This section is empty.

Types

type Grant

type Grant struct {
	AccessToken  string
	RefreshToken string
	ExpiresIn    int64
}

Grant is a token response. RefreshToken is empty when the provider kept the one it already issued, and ExpiresIn is zero when it named no lifetime — both are the absence of news rather than a rotation to an empty value.

func ParseGrant

func ParseGrant(raw []byte) (Grant, bool)

ParseGrant reads a token response body. ok is false when the body is not JSON or carries no access_token: an endpoint can answer 200 with an error document, and taking that for a grant would seal an empty token over a working one.

type Params

type Params struct {
	ClientID          string
	TokenEndpoint     string
	TokenEndpointAuth string
	Resource          *string // RFC 8707, when the credential names one
	Scope             *string
	RefreshToken      string
	ClientSecret      string
}

Params is one credential's refresh configuration: the non-secret half from the stored auth document, and the two secrets from its sealed document.

func (Params) BasicNeedle

func (p Params) BasicNeedle() string

BasicNeedle is the base64 composite the client_secret_basic arm sends, and "" for the arms that send none. That composite is not any single secret value, so a caller that scrubs captured text has to register it on its own — a token endpoint reflecting the request's Authorization header would otherwise leak the client secret past needles built from the secrets themselves.

func (Params) Format

func (p Params) Format(f fmt.State, _ rune)

One rendering for every verb, the package prefix included: String already names the type, so `%#v` needs nothing added to it.

func (Params) LogValue

func (p Params) LogValue() slog.Value

func (Params) NewRequest

func (p Params) NewRequest(ctx context.Context) (*http.Request, error)

NewRequest builds the token request. It reads nothing back and dials nothing: the caller supplies the client, which is where the address guard lives.

func (Params) String

func (p Params) String() string

String, Format and LogValue render Params without any of its secrets. This type is shared by callers with different logging habits, and a struct holding a refresh token and a client secret prints both under a bare `%v` or a structured log of the whole value. Three methods, because none of them covers the others: fmt reaches String for %v and its kin but past it for `%#v` and for a mismatched verb like %d, which is what Format catches (the reasoning is spelled out at internal/modeltest's Config, which redacts a credential the same way and for the same reason); and a structured handler reaches LogValue before it would marshal the fields.

Four of the fields are secrets, not two. The create-time grammar accepts a token endpoint carrying userinfo (internal/api, validateEndpointURL), and takes the RFC 8707 resource indicator as free text with no grammar at all, so either can be `https://id:secret@host/` — the reason the executor redacts these URLs by value out of everything it stores.

%p is the one route left open, and nothing here can close it: fmt resolves it before consulting any method. internal/modeltest's Config spells that out at length, and the reasoning applies unchanged.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL