auth

package
v0.9.0 Latest Latest
Warning

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

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

Documentation

Overview

Package auth is the internal Safeguard authentication broker. It runs the two-step RSTS-then-LoginResponse login for every credential strategy and returns a Safeguard user token.

This package imports neither the root safeguard package nor the browser and devicecode add-on packages, so there is no import cycle: the root package and the add-ons call in with a host, an API version, and ready-built HTTP transports (as HTTPClient values), and receive a user token out. It knows the RSTS and Core wire protocol; it knows nothing about the public Client, Secret, or Option types.

Index

Constants

This section is empty.

Variables

View Source
var ErrDeviceCodeDenied = errors.New("safeguard/auth: device code authorization was denied")

ErrDeviceCodeDenied indicates the user denied the device-code authorization request; the appliance reported access_denied. Compare with errors.Is.

View Source
var ErrDeviceCodeExpired = errors.New("safeguard/auth: device code expired before authorization completed")

ErrDeviceCodeExpired indicates a device-code login was not completed before the user code expired, either because the polling deadline elapsed or because the appliance reported expired_token. Compare with errors.Is.

View Source
var ErrLoginResponseFailed = errors.New("safeguard/auth: login response was not successful")

ErrLoginResponseFailed indicates the Core Token/LoginResponse exchange did not return a success status. Compare with errors.Is.

View Source
var ErrMissingToken = errors.New("safeguard/auth: authentication response contained no token")

ErrMissingToken indicates a login step returned a success status but no token where one was expected.

View Source
var ErrSecondaryFactorFailed = errors.New("safeguard/auth: multi-factor authentication failed")

ErrSecondaryFactorFailed indicates the appliance rejected the supplied secondary (multi-factor) authentication code. Compare with errors.Is.

View Source
var ErrSecondaryFactorRequired = errors.New("safeguard/auth: multi-factor authentication is required but no secondary factor was provided")

ErrSecondaryFactorRequired indicates a PKCE login reached a secondary (multi-factor) authentication step but the caller supplied no secondary factor provider. Compare with errors.Is.

Functions

func AcquireBrowserLoopbackURL

func AcquireBrowserLoopbackURL(ctx context.Context, cfg Config, httpClient HTTPClient, authorizeURL, provider, username string, password []byte, secondary SecondaryFactorProvider) (string, error)

AcquireBrowserLoopbackURL drives the RSTS form controller for a browser authorize URL and returns the loopback redirect URL, complete with the oauth authorization code, that a real system browser would be navigated to after the user signs in. It exists so the browser add-on can be exercised end-to-end against a live appliance without a human at a browser: a live test supplies a browser opener that calls this and then delivers the returned URL to the add-on's loopback listener. Production browser login opens a real system browser and never calls this.

authorizeURL is the URL BrowserAuthorizeURL produced (it carries the PKCE challenge and loopback port). provider selects the RSTS directory (empty defaults to the local provider); username and password are the primary credentials; secondary, when non-nil, satisfies a multi-factor challenge.

func BrowserAuthorizeURL

func BrowserAuthorizeURL(cfg Config, challenge string, port int, username string) string

BrowserAuthorizeURL builds the RSTS authorize URL the browser flow opens. port is the loopback TCP port the add-on is listening on for the redirect; username, when non-empty, is passed as login_hint to pre-fill the appliance login form. No client_id, scope, or state is sent, matching the reference SDKs.

func ExchangeRSTSToken

func ExchangeRSTSToken(ctx context.Context, cfg Config, rstsToken []byte) ([]byte, error)

ExchangeRSTSToken exchanges an already-obtained RSTS access token for a Safeguard user token over the server-trust transport. It is used by the interactive add-on flows (browser, device code) after they obtain an RSTS token through OAuth.

func LoginCertificate

func LoginCertificate(ctx context.Context, cfg Config, provider string) ([]byte, error)

LoginCertificate performs a certificate (client-credentials) login over the client-certificate transport and returns the Safeguard user token. An empty provider defaults to the certificate scope.

func LoginPKCE

func LoginPKCE(ctx context.Context, cfg Config, provider, username string, password []byte, secondary SecondaryFactorProvider) ([]byte, error)

LoginPKCE performs the PKCE non-interactive (headless) login and returns the Safeguard user token. provider selects the RSTS directory (empty defaults to the local provider); username and password are the primary credentials. secondary, when non-nil, is consulted if the appliance requires multi-factor authentication; when the appliance requires it and secondary is nil, the login fails with ErrSecondaryFactorRequired.

func LoginPassword

func LoginPassword(ctx context.Context, cfg Config, provider, username string, password []byte) ([]byte, error)

LoginPassword performs a Resource Owner Grant login and returns the Safeguard user token. An empty provider defaults to the local scope; a non-empty provider is resolved to its RSTS scope.

func PollDeviceCode

func PollDeviceCode(ctx context.Context, cfg Config, httpClient HTTPClient, deviceCode string, interval, expiresIn time.Duration) ([]byte, error)

PollDeviceCode polls the RSTS token endpoint until the user completes the device-code login, then exchanges the resulting RSTS token for a Safeguard user token. It waits interval between polls (honoring a slow_down response by backing off) and gives up after expiresIn, returning ErrDeviceCodeExpired on timeout or expired_token and ErrDeviceCodeDenied when the user declines. The context bounds the whole wait and each poll.

func RedeemBrowserCode

func RedeemBrowserCode(ctx context.Context, cfg Config, httpClient HTTPClient, code, verifier string) ([]byte, error)

RedeemBrowserCode exchanges an authorization code captured by the browser flow for a Safeguard user token: it redeems the code for an RSTS access token over httpClient and then performs the Core LoginResponse exchange. verifier is the PKCE verifier whose challenge was placed in the authorize URL.

func ResolveProviderScope

func ResolveProviderScope(ctx context.Context, cfg Config, provider, defaultProviderID string) (string, error)

ResolveProviderScope maps a caller-supplied provider identifier to the RSTS scope string used in a grant. An empty provider yields the default scope (rsts:sts:primaryproviderid:<defaultProviderID>). A non-empty provider is matched against the appliance's authentication providers; if no provider is found the identifier is used to build the scope directly, matching the behavior of the reference SDKs.

Types

type Config

type Config struct {
	// Host is the appliance host. It may include a scheme; https is assumed when
	// absent. A trailing slash is ignored.
	Host string
	// APIVersion is the Core API version segment, for example "v4".
	APIVersion string
	// HTTPClient is the server-trust HTTP transport. It must not be nil.
	HTTPClient HTTPClient
	// CertHTTPClient is the client-certificate HTTP transport, required only for
	// certificate login.
	CertHTTPClient HTTPClient
}

Config carries everything a login flow needs from the caller. HTTPClient is the server-trust transport used by password, PKCE, and token-exchange calls; CertHTTPClient is the client-certificate transport used by certificate login and is required only for LoginCertificate.

type DeviceCodeChallenge

type DeviceCodeChallenge struct {
	// DeviceCode is the opaque code presented back to the token endpoint while
	// polling. It is not shown to the user.
	DeviceCode string
	// UserCode is the short code the user enters at the verification URI.
	UserCode string
	// VerificationURI is where the user goes to enter the user code.
	VerificationURI string
	// VerificationURIComplete is the verification URI with the user code embedded,
	// suitable for a QR code or direct link.
	VerificationURIComplete string
	// Interval is how long to wait between polls.
	Interval time.Duration
	// ExpiresIn is how long the user code remains valid.
	ExpiresIn time.Duration
}

DeviceCodeChallenge is the result of starting a device-code login: the codes and URIs shown to the user, the opaque device code used for polling, and the interval and lifetime that bound the poll loop.

func StartDeviceCode

func StartDeviceCode(ctx context.Context, cfg Config, httpClient HTTPClient) (DeviceCodeChallenge, error)

StartDeviceCode begins a device-code login by requesting a device authorization from RSTS. The returned challenge carries the codes to display and the timing that bounds PollDeviceCode.

type HTTPClient

type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPClient performs HTTP requests. The root package satisfies it with an *http.Client bound to a particular TLS identity (server-trust for password and PKCE flows, a client-certificate transport for certificate login), so the broker never builds transports or decides TLS policy itself.

type PKCEPair

type PKCEPair struct {
	// Verifier is the base64url (no padding) code verifier sent in the token
	// exchange. It must never be placed in the authorize URL.
	Verifier string
	// Challenge is the base64url (no padding) S256 challenge placed in the
	// authorize URL.
	Challenge string
}

PKCEPair is a PKCE code verifier and its derived S256 challenge for a single interactive login. The verifier is short-lived: the browser package holds it only between building the authorize URL and redeeming the authorization code.

func NewPKCEPair

func NewPKCEPair() (PKCEPair, error)

NewPKCEPair generates a fresh PKCE verifier and its S256 challenge using the same random-material size as the headless flow.

type RequestError

type RequestError struct {
	// Op names the failing step, for example "rsts grant" or "login response".
	Op string
	// StatusCode is the HTTP status, or 0 when no response was received.
	StatusCode int
	// Err is the underlying transport error, if any.
	Err error
	// contains filtered or unexported fields
}

RequestError is returned when an authentication HTTP call fails, either because the transport failed or because the appliance returned a non-success status. The root package inspects StatusCode to map the failure onto its public error hierarchy (for example a 401 to AuthenticationError). The stored body is bounded and available only through Body; it is never included in Error because RSTS and login payloads can echo sensitive material.

func (*RequestError) Body

func (e *RequestError) Body() []byte

Body returns a copy of the bounded response body retained for diagnostics. It may contain sensitive data and is never logged automatically.

func (*RequestError) Error

func (e *RequestError) Error() string

Error implements error. It deliberately omits the response body.

func (*RequestError) Unwrap

func (e *RequestError) Unwrap() error

Unwrap returns the underlying transport error so errors.Is/As reach the cause.

type SecondaryFactorProvider

type SecondaryFactorProvider func(ctx context.Context, prompt string) ([]byte, error)

SecondaryFactorProvider supplies a multi-factor one-time code given the appliance's human-readable prompt. It is invoked only when the primary login step reports that a secondary provider is required. Returning an error aborts the login. The returned bytes are zeroed by the caller after use.

Jump to

Keyboard shortcuts

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