devicekey

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package devicekey is the client side of AuthKit's device-key protocol, for CLIs and machines. A machine holds an Ed25519 key, enrolls it once with a code emailed to the account (plus the account's second factor, when it has one), then signs in with it for short access tokens. There is no refresh token: signing a fresh challenge is the refresh.

A device key signs domain || 0x00 || challenge, where challenge is the server's raw 32-byte challenge. The domain separates enrollment from login, so neither signature can be replayed as the other.

The package depends only on the standard library and iam.

Index

Constants

View Source
const (
	EnrollmentDomain = "authkit.device-key-enrollment/1"
	LoginDomain      = "authkit.device-key-login/1"
)

Signing domains. AuthKit verifies with these same constants.

Variables

This section is empty.

Functions

func Message

func Message(domain string, challenge []byte) []byte

Message is the byte string a device key signs for the raw challenge in domain.

func SignEnrollment

func SignEnrollment(key crypto.Signer, challenge string) (string, error)

SignEnrollment signs an enrollment challenge as it arrives on the wire (base64url) and returns the base64url signature the finish request carries.

func SignLogin

func SignLogin(key crypto.Signer, challenge string) (string, error)

SignLogin is SignEnrollment for a login challenge.

Types

type Client

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

Client speaks the device-key protocol to one AuthKit mount. A refusal is an iam.Error decoded from AuthKit's error envelope (iam.AsError, errors.Is against the iam sentinels); a device-key route answers 404 with no code when the host has not enabled device keys.

func NewClient

func NewClient(baseURL string, hc *http.Client) (*Client, error)

NewClient returns a Client for the AuthKit JSON API at baseURL: the mount's origin and API prefix, such as "https://example.com/api/v1". A nil hc uses http.DefaultClient.

func (*Client) BeginEnrollment

func (c *Client) BeginEnrollment(ctx context.Context, email string, key ed25519.PublicKey, label string) (Enrollment, error)

BeginEnrollment asks AuthKit to email a code to email for enrolling key. label names the machine to the account owner (at most 128 bytes). A new address creates the account where registration is open.

func (*Client) FinishEnrollment

func (c *Client) FinishEnrollment(ctx context.Context, e Enrollment, key crypto.Signer, code, secondFactor string) (Session, error)

FinishEnrollment proves the emailed code and possession of key (the enrollment's key), enrolls it and signs it in. secondFactor is "" until a *SecondFactorRequired asks for one. The session's token also proves the account's email, which RevokeOthers requires: re-enrolling a key already enrolled on the account is how a machine obtains that proof.

func (*Client) List

func (c *Client) List(ctx context.Context, token string) ([]iam.DeviceKey, error)

List returns the account's live device keys with a device-key access token: the device keys of GET /me/sign-in-keys. That view has no public key or revocation time, so PublicKey and RevokedAt are unset.

func (*Client) Login

func (c *Client) Login(ctx context.Context, id string, key crypto.Signer) (Session, error)

Login signs in with the enrolled key id and its private key.

func (*Client) Logout added in v0.149.0

func (c *Client) Logout(ctx context.Context, token string) error

Logout signs the machine out: it revokes the token's own key. It is retry-safe.

func (*Client) Revoke

func (c *Client) Revoke(ctx context.Context, token, id string) error

Revoke revokes the account's key id with a device-key access token of a recent sign-in (DELETE /me/sign-in-keys/{id}). Logout revokes the token's own key.

func (*Client) RevokeOthers

func (c *Client) RevokeOthers(ctx context.Context, token string) error

RevokeOthers revokes every key of the account but the token's own. The token must come from FinishEnrollment; a Login token is refused (forbidden).

type Enrollment

type Enrollment struct {
	ID        string
	Challenge string
	PublicKey ed25519.PublicKey
	ExpiresAt time.Time
}

Enrollment is a pending enrollment: BeginEnrollment's answer, finished with the emailed code before ExpiresAt. It holds no secret and may be persisted between the two calls.

type SecondFactorRequired

type SecondFactorRequired struct {
	Method string
	// contains filtered or unexported fields
}

SecondFactorRequired is FinishEnrollment's answer when the account has a second factor: retry with the same enrollment and emailed code plus that factor's code. Method is "totp", "sms" (AuthKit has just sent the code) or "backup_code"; the account's email factor never counts, since it reads the mailbox the enrollment code went to. It wraps the decoded iam.Error.

func (*SecondFactorRequired) Error

func (e *SecondFactorRequired) Error() string

func (*SecondFactorRequired) Unwrap

func (e *SecondFactorRequired) Unwrap() error

type Session

type Session struct {
	AccessToken string
	ExpiresAt   time.Time
	DeviceKey   iam.DeviceKey
}

Session is a device key's sign-in: an access token and the key. It has no refresh token; sign in again with the key once ExpiresAt passes.

Jump to

Keyboard shortcuts

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