cboxid

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 18 Imported by: 0

README

cboxid — Cbox ID client for Go

Go Reference

Turnkey Cbox ID client for Go, built for command-line tools: log a CLI in with the device authorization grant (RFC 8628) — the flow the GitHub CLI uses — where the user approves a short code in a browser on any device while your program polls.

It also supports the standard authorization-code + PKCE flow for server apps, plus machine tokens, UserInfo, RFC 7662 introspection and webhook verification. The id_token and OIDC plumbing are handled by the vetted go-oidc and x/oauth2 — no hand-rolled crypto.

Install

go get github.com/cboxdk/id-go

CLI login (device flow)

client, _ := cboxid.New(ctx, cboxid.Config{
    Issuer:      "https://id.acme.com",
    ClientID:    "client_...",
    RedirectURI: "http://localhost", // unused by the device flow, but required
    Scopes:      []string{"openid", "profile", "email", "offline_access"},
})

auth, _ := client.RequestDeviceAuthorization(ctx, cboxid.DeviceParams{})
fmt.Printf("Visit %s and enter code %s\n", auth.VerificationURI, auth.UserCode)

// Blocks until the user approves (or the code expires); honors the poll interval.
user, err := client.PollDeviceToken(ctx, auth)
fmt.Printf("Signed in as %s\n", user.Email)
// Persist user.Token (with its refresh token) to your CLI config for next time.

A complete, runnable example is in examples/cli.

Server login (authorization code + PKCE)

req := client.CreateAuthorizationRequest(cboxid.AuthParams{})
// persist req.State, req.CodeVerifier, req.Nonce; redirect the user to req.URL

// on the callback:
user, err := client.Authenticate(ctx,
    cboxid.Callback{Code: code, State: state},
    cboxid.Stored{State: req.State, CodeVerifier: req.CodeVerifier, Nonce: req.Nonce},
)

Back-channel calls

token, _ := client.MachineToken(ctx, cboxid.MachineTokenParams{Scopes: []string{"reports.read"}})
claims, _ := client.UserInfo(ctx, user.AccessToken)
result, _ := client.Introspect(ctx, someToken) // RFC 7662

Verify webhooks

ok := cboxid.VerifyWebhook(rawBody, r.Header.Get("X-Cbox-Signature"), webhookSecret, 300)

Errors

Errors wrap the sentinels cboxid.ErrInvalidState, cboxid.ErrAuthentication and cboxid.ErrConfiguration — match them with errors.Is. A state mismatch is ErrInvalidState; treat it as a fresh start, not a user-facing error.

Security & scope

Login is hardened by default — PKCE, state, nonce (auth-code flow), and full id_token verification (signature/issuer/audience) via go-oidc. Key accounts on user.ID (the stable subject), not on email.

This is a client. It authenticates users and calls a Cbox ID instance's standard endpoints; it does not configure SSO, run SCIM, or manage organizations — those are platform capabilities of cboxdk/laravel-id.

Report vulnerabilities via this repo's GitHub Private Vulnerability Reporting.

License

MIT © Cbox.

Documentation

Overview

Package cboxid is a turnkey Cbox ID client for Go. It speaks standard OpenID Connect against a Cbox ID instance — so integrating is a redirect and a callback, not a rewrite — and adds the conveniences a hosted-identity product needs: a redirect to the instance's hosted profile page, and back-channel helpers (machine tokens, userinfo, RFC 7662 introspection, webhook verification).

Login is hardened by default: PKCE (S256), a CSRF state check, a nonce, and full id_token signature + issuer + audience verification against the instance's JWKS. The heavy lifting is delegated to the vetted github.com/coreos/go-oidc/v3 and golang.org/x/oauth2 — no hand-rolled crypto or JWT parsing.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrConfiguration indicates a missing or invalid configuration value.
	ErrConfiguration = errors.New("cboxid: configuration error")
	// ErrInvalidState indicates the login state did not match — a forged or stale
	// callback. Treat it as a fresh start, not an error to show the user.
	ErrInvalidState = errors.New("cboxid: login state did not match")
	// ErrAuthentication indicates login could not be completed, or a token failed
	// verification.
	ErrAuthentication = errors.New("cboxid: authentication failed")
)

Functions

func VerifyWebhook

func VerifyWebhook(payload string, signatureHeader string, secret string, toleranceSeconds int) bool

VerifyWebhook verifies a Cbox ID webhook / inline-action signature. The header is "t={unix},v1={hex hmac}" — an HMAC-SHA256 over "{timestamp}.{raw body}", valid within toleranceSeconds. Pass the RAW request body, not a re-serialized copy. It returns false (never panics) on any problem.

Types

type AuthParams

type AuthParams struct {
	Scopes    []string // overrides the configured default scopes
	Prompt    string   // e.g. "login" or "consent"
	LoginHint string
}

AuthParams optionally customizes a single authorization request.

type AuthorizationRequest

type AuthorizationRequest struct {
	URL          string
	State        string
	CodeVerifier string
	Nonce        string
}

AuthorizationRequest is returned by CreateAuthorizationRequest. Persist State, CodeVerifier and Nonce (e.g. in the session) and hand them back to Authenticate.

type Callback

type Callback struct {
	Code  string
	State string
	Error string
}

Callback holds the query parameters as they arrive on your callback route.

type CboxUser

type CboxUser struct {
	ID             string
	Email          string
	Name           string
	OrganizationID string
	Claims         map[string]any
	AccessToken    string
	RefreshToken   string
	IDToken        string
	Expiry         time.Time
	// Token is the raw oauth2 token, e.g. for building an authenticated client.
	Token *oauth2.Token
}

CboxUser is the authenticated user. ID is the stable subject (sub) you key your local account on. Claims is the full verified id_token + userinfo claim set.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a Cbox ID client. Construct it with New and share it; it is safe for concurrent use.

func New

func New(ctx context.Context, cfg Config) (*Client, error)

New builds a Client, discovering the instance's endpoints and JWKS from {issuer}/.well-known/openid-configuration.

func (*Client) Authenticate

func (c *Client) Authenticate(ctx context.Context, cb Callback, stored Stored) (*CboxUser, error)

Authenticate completes login on your callback route: it verifies the state, exchanges the code with the PKCE verifier, verifies the id_token, and returns the user. It returns ErrInvalidState on a state mismatch and wraps ErrAuthentication on any other failure.

func (*Client) CreateAuthorizationRequest

func (c *Client) CreateAuthorizationRequest(params AuthParams) AuthorizationRequest

CreateAuthorizationRequest begins login. Redirect the user to the returned URL and persist State, CodeVerifier and Nonce for Authenticate.

func (*Client) Introspect

func (c *Client) Introspect(ctx context.Context, token string) (map[string]any, error)

Introspect performs RFC 7662 token introspection (confidential-client auth). The returned map's "active" field tells you if the token is currently valid.

func (*Client) LogoutURL

func (c *Client) LogoutURL(returnTo string) string

LogoutURL is the RP-initiated logout URL, or "" when the instance advertises none.

func (*Client) MachineToken

func (c *Client) MachineToken(ctx context.Context, params MachineTokenParams) (string, error)

MachineToken returns a machine (client-credentials) access token for calling Cbox ID APIs as your app, not on a user's behalf. Requires a client secret.

func (*Client) PollDeviceToken

func (c *Client) PollDeviceToken(ctx context.Context, auth *DeviceAuth) (*CboxUser, error)

PollDeviceToken blocks until the user approves the DeviceAuth (or it expires), honoring the poll interval and the authorization_pending / slow_down signals, then verifies the id_token and returns the user. Pass a context with a deadline to bound the wait. There is no nonce in the device flow, so the nonce check is skipped; signature, issuer and audience are still verified.

func (*Client) ProfileURL

func (c *Client) ProfileURL(returnTo string) string

ProfileURL is the URL of the instance's hosted account/profile page (self-service password, MFA, passkeys, sessions). A signed-in user is authenticated there by their Cbox ID session; returnTo, when non-empty, is passed so the page can link back to your app.

func (*Client) RequestDeviceAuthorization

func (c *Client) RequestDeviceAuthorization(ctx context.Context, params DeviceParams) (*DeviceAuth, error)

RequestDeviceAuthorization starts the device authorization grant — the flow a CLI or a TV app uses: the user authorizes on a second device (phone/laptop) while your program polls. Requires the instance to support the device grant.

func (*Client) UserInfo

func (c *Client) UserInfo(ctx context.Context, accessToken string) (map[string]any, error)

UserInfo returns the OIDC userinfo claims for an access token.

type Config

type Config struct {
	// Issuer is the base URL of the Cbox ID instance, e.g. https://id.acme.com.
	Issuer string
	// ClientID is your registered OAuth client id.
	ClientID string
	// ClientSecret is required for confidential apps, machine tokens and
	// introspection. Leave empty for public clients doing only PKCE login.
	ClientSecret string
	// RedirectURI is your callback URL, registered on the client.
	RedirectURI string
	// Scopes requested at login. Defaults to openid, profile, email.
	Scopes []string
	// AccountPath is the instance's hosted account page. Defaults to /settings.
	AccountPath string
	// HTTPClient, when set, is used for all back-channel calls (else http.DefaultClient).
	HTTPClient *http.Client
}

Config configures a Client.

type DeviceAuth

type DeviceAuth struct {
	// DeviceCode is the secret your CLI polls with; don't show it to the user.
	DeviceCode string
	// UserCode is the short code the user types on the verification page.
	UserCode string
	// VerificationURI is where the user goes to authorize.
	VerificationURI string
	// VerificationURIComplete embeds the user code, for a clickable link / QR.
	VerificationURIComplete string
	// Expiry is when this authorization stops being valid.
	Expiry time.Time
	// Interval is the minimum seconds between polls.
	Interval int64
	// contains filtered or unexported fields
}

DeviceAuth is a pending device authorization (RFC 8628). Show UserCode to the person and send them to VerificationURI (or VerificationURIComplete, which embeds the code), then call PollDeviceToken.

type DeviceParams

type DeviceParams struct {
	Scopes []string
}

DeviceParams optionally scopes a device authorization.

type MachineTokenParams

type MachineTokenParams struct {
	Scopes   []string
	Resource string // RFC 8707 resource indicator
}

MachineTokenParams optionally scopes a machine token.

type Stored

type Stored struct {
	State        string
	CodeVerifier string
	Nonce        string
}

Stored holds the values you persisted from CreateAuthorizationRequest.

Directories

Path Synopsis
examples
cli command
Command cli is a minimal example of logging a CLI in to Cbox ID using the device authorization grant (RFC 8628) — the same flow the GitHub CLI uses: the tool prints a short code, the user approves it in a browser on any device, and the CLI receives the tokens.
Command cli is a minimal example of logging a CLI in to Cbox ID using the device authorization grant (RFC 8628) — the same flow the GitHub CLI uses: the tool prints a short code, the user approves it in a browser on any device, and the CLI receives the tokens.

Jump to

Keyboard shortcuts

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