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 ¶
- Variables
- func VerifyWebhook(payload string, signatureHeader string, secret string, toleranceSeconds int) bool
- type AuthParams
- type AuthorizationRequest
- type Callback
- type CboxUser
- type Client
- func (c *Client) Authenticate(ctx context.Context, cb Callback, stored Stored) (*CboxUser, error)
- func (c *Client) CreateAuthorizationRequest(params AuthParams) AuthorizationRequest
- func (c *Client) Introspect(ctx context.Context, token string) (map[string]any, error)
- func (c *Client) LogoutURL(returnTo string) string
- func (c *Client) MachineToken(ctx context.Context, params MachineTokenParams) (string, error)
- func (c *Client) Manifest() Manifest
- func (c *Client) PollDeviceToken(ctx context.Context, auth *DeviceAuth) (*CboxUser, error)
- func (c *Client) ProfileURL(returnTo string) string
- func (c *Client) PublishManifest(ctx context.Context) (Summary, error)
- func (c *Client) RequestDeviceAuthorization(ctx context.Context, params DeviceParams) (*DeviceAuth, error)
- func (c *Client) UserInfo(ctx context.Context, accessToken string) (map[string]any, error)
- type Config
- type DeviceAuth
- type DeviceParams
- type MachineTokenParams
- type Manifest
- type Permission
- type Role
- type Stored
- type Summary
Constants ¶
This section is empty.
Variables ¶
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") // ErrManifestRejected indicates Cbox ID refused an authorization-manifest push — // e.g. the client lacks the apps.manifest scope, or the manifest was malformed. // The wrapped message carries the HTTP status and the server's response body. ErrManifestRejected = errors.New("cboxid: manifest push rejected") )
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 ¶
AuthorizationRequest is returned by CreateAuthorizationRequest. Persist State, CodeVerifier and Nonce (e.g. in the session) and hand them back to Authenticate.
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 ¶
New builds a Client, discovering the instance's endpoints and JWKS from {issuer}/.well-known/openid-configuration.
func (*Client) Authenticate ¶
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 ¶
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 ¶
LogoutURL is the RP-initiated logout URL, or "" when the instance advertises none.
func (*Client) MachineToken ¶
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) Manifest ¶ added in v0.2.0
Manifest returns the manifest that PublishManifest would send: the configured permissions and roles with a stable content hash as its version. The hash is the first 16 hex chars of the SHA-256 over the JSON-encoded permissions+roles, so an unchanged catalog yields an unchanged version.
func (*Client) PollDeviceToken ¶
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 ¶
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) PublishManifest ¶ added in v0.2.0
PublishManifest pushes this app's declared roles and permissions (Config.Roles and Config.Permissions) to Cbox ID, and returns the server's sync summary. Run it on deploy so the Cbox ID console always reflects the app's current catalog; it is idempotent — republishing an unchanged manifest is a no-op.
It mints a client-credentials token scoped to apps.manifest, then POSTs the manifest to {issuer}/api/v1/apps/manifest with that bearer token. Requires a ClientSecret and a client that holds the apps.manifest scope. It returns ErrConfiguration when nothing is declared or credentials are missing, and wraps ErrManifestRejected when Cbox ID refuses the push.
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.
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
// Permissions and Roles declare this app's authorization catalog in code, for
// PublishManifest to push to Cbox ID on deploy. Cbox ID owns identity and who
// holds what; the app owns what a role means. Leave empty if you don't publish a
// manifest. Requires the client to hold the apps.manifest scope.
Permissions []Permission
Roles []Role
}
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 ¶
MachineTokenParams optionally scopes a machine token.
type Manifest ¶ added in v0.2.0
type Manifest struct {
Permissions []Permission `json:"permissions"`
Roles []Role `json:"roles"`
Version string `json:"version"`
}
Manifest is the app's declared authorization catalog as it is sent to Cbox ID: its permissions and roles plus a content-derived Version, so republishing an unchanged catalog is a server-side no-op. Its JSON shape is the contract shared by every Cbox ID SDK.
type Permission ¶ added in v0.2.0
type Permission struct {
Key string `json:"key"`
Description string `json:"description,omitempty"`
}
Permission is one authorization permission the app declares. Key is a "feature:action" slug (e.g. "invoices:create"); Description is human-facing copy shown in the Cbox ID console.
type Role ¶ added in v0.2.0
type Role struct {
Key string `json:"key"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Permissions []string `json:"permissions"`
}
Role is one authorization role the app declares. Permissions must reference keys of declared Permissions. Cbox ID assigns roles to users and returns them in the token's claims; the app decides what each role is allowed to do.
type Summary ¶ added in v0.2.0
type Summary struct {
Unchanged bool `json:"unchanged"`
RolesDeclared int `json:"roles_declared"`
PermissionsDeclared int `json:"permissions_declared"`
OrphanedRoles []string `json:"orphaned_roles,omitempty"`
OrphanedPermissions []string `json:"orphaned_permissions,omitempty"`
}
Summary is Cbox ID's response to a manifest push. Unchanged is true when the pushed catalog matched what was already synced. Orphaned* list keys the app once declared but dropped — Cbox ID keeps and flags them rather than deleting them.
Source Files
¶
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. |
|
publish-manifest
command
Command publish-manifest declares this app's authorization roles and permissions in code and pushes them to Cbox ID — the Go counterpart of Laravel's `php artisan cbox-id:publish-manifest`.
|
Command publish-manifest declares this app's authorization roles and permissions in code and pushes them to Cbox ID — the Go counterpart of Laravel's `php artisan cbox-id:publish-manifest`. |