Documentation
¶
Overview ¶
Package deviceauth provides RFC 8628 OAuth 2.0 Device Authorization Grant capabilities (reserved module).
Index ¶
- Constants
- Variables
- func RegisterSchema(s *schema.Schema) error
- type AuthorizeInput
- type Capability
- type Config
- type DenyInput
- type DeviceAuthAuthorizedPayload
- type DeviceAuthConsumedPayload
- type DeviceAuthDeniedPayload
- type DeviceAuthStartedPayload
- type DeviceAuthorization
- type DeviceAuthorizationRequestInput
- type DeviceAuthorizationResponse
- type DeviceGrant
- type DeviceStatus
- type Module
- type Option
- type PollInput
- type PollResponse
- type UserCodeVerificationResult
- type VerifyUserCodeInput
Constants ¶
const ( DefaultExpiresIn = 10 * time.Minute DefaultPollingInterval = 5 * time.Second DefaultSlowDownIncrement = 5 * time.Second DefaultMaxFailedAttempts = 5 DefaultVerificationURI = "https://example.com/device" DefaultRateLimitPerMinute = 10 )
Default configuration parameters according to RFC 8628 recommendations.
const ( // OAuthErrAuthorizationPending indicates the user has not yet completed the authorization flow. OAuthErrAuthorizationPending = "authorization_pending" // OAuthErrSlowDown indicates the client is polling too frequently; interval must be increased by 5s. OAuthErrSlowDown = "slow_down" // OAuthErrAccessDenied indicates the user explicitly denied the authorization request. OAuthErrAccessDenied = "access_denied" // OAuthErrExpiredToken indicates the device code or user code has expired. OAuthErrExpiredToken = "expired_token" // OAuthErrInvalidGrant indicates the device code is invalid, revoked, or already consumed. OAuthErrInvalidGrant = "invalid_grant" )
RFC 8628 Standard Device Authorization Error Codes
const ( EventDeviceAuthStarted auth.EventName = "deviceauth.started" EventDeviceAuthAuthorized auth.EventName = "deviceauth.authorized" EventDeviceAuthDenied auth.EventName = "deviceauth.denied" EventDeviceAuthConsumed auth.EventName = "deviceauth.consumed" )
Audit and lifecycle event identifiers for the Device Authorization Grant.
const (
ModelDeviceGrants = "device_grants"
)
const PluginID = "device-authorization"
PluginID identifies this plugin in the GoModularAuth runtime.
Variables ¶
var ( // ErrAuthorizationPending indicates the authorization request is pending user approval. ErrAuthorizationPending = errors.New(OAuthErrAuthorizationPending) // ErrSlowDown indicates the client polled before the allowed interval; interval increases by 5 seconds. ErrSlowDown = errors.New(OAuthErrSlowDown) // ErrAccessDenied indicates the user explicitly denied the authorization request. ErrAccessDenied = errors.New(OAuthErrAccessDenied) // ErrExpiredToken indicates the device authorization request has expired. ErrExpiredToken = errors.New(OAuthErrExpiredToken) // ErrInvalidGrant indicates the device code is invalid or has already been consumed (replay prevented). ErrInvalidGrant = errors.New(OAuthErrInvalidGrant) // ErrInvalidUserCode indicates the user-entered verification code was not found or is invalid. ErrInvalidUserCode = errors.New("device auth: invalid or unknown user code") // ErrMaxAttemptsExceeded indicates too many failed attempts were made against a user code. ErrMaxAttemptsExceeded = errors.New("device auth: maximum verification attempts exceeded") // ErrAlreadyAuthorized indicates the user code was already approved. ErrAlreadyAuthorized = errors.New("device auth: request is already authorized") // ErrAlreadyDenied indicates the user code was already denied. ErrAlreadyDenied = errors.New("device auth: request is already denied") // ErrAlreadyConsumed indicates the grant has already been exchanged for tokens. ErrAlreadyConsumed = errors.New("device auth: request has already been consumed") // ErrRateLimited indicates request rate limit has been exceeded. ErrRateLimited = errors.New("device auth: rate limit exceeded") // ErrInvalidClient indicates the client ID is missing or does not match the initiated grant. ErrInvalidClient = errors.New("device auth: invalid client") // ErrInvalidInput indicates missing or invalid request parameters. ErrInvalidInput = errors.New("device auth: invalid input parameters") // ErrAdapterRequired indicates that a database adapter was not configured. ErrAdapterRequired = errors.New("device auth: adapter is required") // ErrStoreRequired is an alias for ErrAdapterRequired for backward compatibility. ErrStoreRequired = ErrAdapterRequired )
Functions ¶
func RegisterSchema ¶
RegisterSchema registers the device_grants model into the compiled schema.
Types ¶
type AuthorizeInput ¶
type AuthorizeInput struct {
// UserCode is the target user code being authorized. Required.
UserCode string `json:"user_code"`
// Principal identifies the authenticated user approving the request. Required.
Principal auth.Principal `json:"principal"`
// Scope specifies approved scopes (can be subset of requested).
Scope string `json:"scope,omitempty"`
}
AuthorizeInput contains parameters for the end user approving the device request.
type Capability ¶
type Capability = DeviceAuthorization
Capability is an alias for DeviceAuthorization to support standard capability discovery conventions.
type Config ¶
type Config struct {
VerificationURI string
VerificationURIComplete string
ExpiresIn time.Duration
PollingInterval time.Duration
SlowDownIncrement time.Duration
MaxFailedAttempts int
RateLimitPerMinute int64
}
Config encapsulates configuration settings for the device authorization plugin.
type DenyInput ¶
type DenyInput struct {
// UserCode is the target user code being denied. Required.
UserCode string `json:"user_code"`
// Principal identifies the authenticated user denying the request. Required.
Principal auth.Principal `json:"principal"`
}
DenyInput contains parameters for the end user rejecting the device request.
type DeviceAuthAuthorizedPayload ¶
type DeviceAuthAuthorizedPayload struct {
GrantID string `json:"grant_id"`
ClientID string `json:"client_id"`
UserCode string `json:"user_code"`
UserID string `json:"user_id"`
AuthorizedAt time.Time `json:"authorized_at"`
}
DeviceAuthAuthorizedPayload describes user authorization of a device grant.
type DeviceAuthConsumedPayload ¶
type DeviceAuthConsumedPayload struct {
GrantID string `json:"grant_id"`
ClientID string `json:"client_id"`
UserID string `json:"user_id"`
ConsumedAt time.Time `json:"consumed_at"`
}
DeviceAuthConsumedPayload describes single-use token issuance for a device grant.
type DeviceAuthDeniedPayload ¶
type DeviceAuthDeniedPayload struct {
GrantID string `json:"grant_id"`
ClientID string `json:"client_id"`
UserCode string `json:"user_code"`
DeniedAt time.Time `json:"denied_at"`
}
DeviceAuthDeniedPayload describes user rejection of a device grant.
type DeviceAuthStartedPayload ¶
type DeviceAuthStartedPayload struct {
GrantID string `json:"grant_id"`
ClientID string `json:"client_id"`
UserCode string `json:"user_code"`
ExpiresAt time.Time `json:"expires_at"`
PollingInterval int `json:"polling_interval"`
CreatedAt time.Time `json:"created_at"`
}
DeviceAuthStartedPayload describes the initiation of a device flow. CRITICAL: NEVER includes the plaintext device_code in events.
type DeviceAuthorization ¶
type DeviceAuthorization interface {
// Start initiates the device flow and returns device and user codes.
Start(ctx context.Context, in DeviceAuthorizationRequestInput) (*DeviceAuthorizationResponse, error)
// Poll checks device authorization status and issues tokens upon user approval.
Poll(ctx context.Context, in PollInput) (*PollResponse, error)
// VerifyUserCode inspects a user code submitted by the user on the verification page.
VerifyUserCode(ctx context.Context, in VerifyUserCodeInput) (*UserCodeVerificationResult, error)
// Authorize records user consent and associates the grant with the authorizing user.
Authorize(ctx context.Context, in AuthorizeInput) error
// Deny records user rejection of the authorization request.
Deny(ctx context.Context, in DenyInput) error
}
DeviceAuthorization defines the RFC 8628 OAuth 2.0 Device Authorization Grant capability. Applications access it via auth.Get[plugins.DeviceAuthorization](a) or auth.Get[deviceauth.DeviceAuthorization](a).
type DeviceAuthorizationRequestInput ¶
type DeviceAuthorizationRequestInput struct {
// ClientID identifies the client application running on the device. Required.
ClientID string `json:"client_id"`
// Scope indicates the requested permission scopes.
Scope string `json:"scope,omitempty"`
// Metadata carries optional device or client properties (e.g. model, OS).
Metadata map[string]string `json:"metadata,omitempty"`
}
DeviceAuthorizationRequestInput contains parameters to initiate a device authorization flow.
type DeviceAuthorizationResponse ¶
type DeviceAuthorizationResponse struct {
// DeviceCode is the high-entropy verification code for device polling.
DeviceCode string `json:"device_code"`
// UserCode is the human-friendly code entered by the user on the verification page.
UserCode string `json:"user_code"`
// VerificationURI is the web URL where the end user enters the UserCode.
VerificationURI string `json:"verification_uri"`
// VerificationURIComplete is the optional URL containing pre-filled user_code.
VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
// ExpiresIn is the lifetime in seconds for the device_code and user_code.
ExpiresIn int `json:"expires_in"`
// Interval is the minimum polling interval in seconds that the device must respect.
Interval int `json:"interval"`
}
DeviceAuthorizationResponse represents the response returned to the device (RFC 8628 Section 3.2).
type DeviceGrant ¶
type DeviceGrant struct {
ID string `json:"id"`
ClientID string `json:"client_id"`
DeviceCodeHash string `json:"device_code_hash"`
UserCode string `json:"user_code"`
Status DeviceStatus `json:"status"`
UserID string `json:"user_id,omitempty"`
Scope string `json:"scope,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
ExpiresAt time.Time `json:"expires_at"`
LastPolledAt *time.Time `json:"last_polled_at,omitempty"`
PollingInterval int `json:"polling_interval"`
FailedAttempts int `json:"failed_attempts"`
AuthorizedAt *time.Time `json:"authorized_at,omitempty"`
ConsumedAt *time.Time `json:"consumed_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
DeviceGrant represents the authoritative state of an RFC 8628 device authorization session.
type DeviceStatus ¶
type DeviceStatus string
DeviceStatus represents the lifecycle state of a device authorization grant.
const ( // StatusPending indicates the authorization request is awaiting user interaction. StatusPending DeviceStatus = "pending" // StatusAuthorized indicates the user approved the request, ready for device token exchange. StatusAuthorized DeviceStatus = "authorized" // StatusDenied indicates the user rejected the authorization request. StatusDenied DeviceStatus = "denied" // StatusConsumed indicates the device code has been exchanged for credentials (single-use fulfilled). StatusConsumed DeviceStatus = "consumed" )
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module implements auth.PluginModule using plugin-sdk.
type Option ¶
type Option func(*Config)
Option configures device authorization plugin settings.
func WithExpiresIn ¶
WithExpiresIn sets the validity lifetime of issued device and user codes.
func WithMaxFailedAttempts ¶
WithMaxFailedAttempts sets the maximum bad user-code attempts before locking the grant.
func WithPollingInterval ¶
WithPollingInterval sets the minimum interval between device poll requests.
func WithRateLimit ¶
WithRateLimit sets the maximum verification requests allowed per minute per IP.
func WithVerificationURI ¶
WithVerificationURI sets the base verification URL where users enter their code.
func WithVerificationURIComplete ¶
WithVerificationURIComplete sets the complete verification URL format.
type PollInput ¶
type PollInput struct {
// DeviceCode is the secret code issued to the device. Required.
DeviceCode string `json:"device_code"`
// ClientID is the client application ID. Required.
ClientID string `json:"client_id"`
// Session holds optional metadata (IP address, User Agent) recorded with the created session.
Session auth.SessionOptions `json:"session,omitempty"`
}
PollInput contains parameters for the device polling token request.
type PollResponse ¶
type PollResponse struct {
// Status indicates the current lifecycle status of the authorization request.
Status DeviceStatus `json:"status"`
// UserID is the subject identifier of the authorizing user when Status == StatusAuthorized or StatusConsumed.
UserID string `json:"user_id,omitempty"`
// Session is the newly established session when authorization is fulfilled.
Session *session.Session `json:"session,omitempty"`
// Token is the plaintext session token returned exactly once upon successful completion.
Token string `json:"token,omitempty"`
}
PollResponse represents the outcome of a device token poll request.
type UserCodeVerificationResult ¶
type UserCodeVerificationResult struct {
// GrantID is the internal grant identifier.
GrantID string `json:"grant_id"`
// ClientID is the client requesting authorization.
ClientID string `json:"client_id"`
// UserCode is the normalized user code.
UserCode string `json:"user_code"`
// Scope indicates requested permissions.
Scope string `json:"scope,omitempty"`
// Metadata contains additional context for display.
Metadata map[string]string `json:"metadata,omitempty"`
// ExpiresAt is the expiration instant.
ExpiresAt time.Time `json:"expires_at"`
}
UserCodeVerificationResult presents grant metadata to the user consent interface.
type VerifyUserCodeInput ¶
type VerifyUserCodeInput struct {
// UserCode is the code entered by the user. Required.
UserCode string `json:"user_code"`
// ClientIP is the caller's IP address used for rate limiting brute-force protection.
ClientIP string `json:"client_ip,omitempty"`
}
VerifyUserCodeInput contains parameters for the user entering the code on the web page.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cache provides rate limiting and temporary throttle helpers for device authorization.
|
Package cache provides rate limiting and temporary throttle helpers for device authorization. |
|
Package events re-exports device authorization audit event identifiers and payload types.
|
Package events re-exports device authorization audit event identifiers and payload types. |
|
Package migrations contains SQL schema migrations for the device-authorization plugin.
|
Package migrations contains SQL schema migrations for the device-authorization plugin. |
|
Package plugins exposes capability aliases for GoModularAuth plugins.
|
Package plugins exposes capability aliases for GoModularAuth plugins. |