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
- func Message(domain string, challenge []byte) []byte
- func SignEnrollment(key crypto.Signer, challenge string) (string, error)
- func SignLogin(key crypto.Signer, challenge string) (string, error)
- type Client
- func (c *Client) BeginEnrollment(ctx context.Context, email string, key ed25519.PublicKey, label string) (Enrollment, error)
- func (c *Client) FinishEnrollment(ctx context.Context, e Enrollment, key crypto.Signer, ...) (Session, error)
- func (c *Client) List(ctx context.Context, token string) ([]iam.DeviceKey, error)
- func (c *Client) Login(ctx context.Context, id string, key crypto.Signer) (Session, error)
- func (c *Client) Logout(ctx context.Context, token string) error
- func (c *Client) Revoke(ctx context.Context, token, id string) error
- func (c *Client) RevokeOthers(ctx context.Context, token string) error
- type Enrollment
- type SecondFactorRequired
- type Session
Constants ¶
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 SignEnrollment ¶
SignEnrollment signs an enrollment challenge as it arrives on the wire (base64url) and returns the base64url signature the finish request carries.
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 ¶
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 ¶
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) Logout ¶ added in v0.149.0
Logout signs the machine out: it revokes the token's own key. It is retry-safe.
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