Documentation
¶
Overview ¶
Package auth signs users in to the admin listener (PHASE1 step 10, security.md "Authentication"): Argon2id passwords, TOTP (RFC 6238), recovery codes, server-side sessions, CSRF protection, throttling and lockout. Permissions are decided by internal/authz.
Secrets at rest: passwords as Argon2id hashes; TOTP secrets encrypted with the auth key (auth.key_file), bound to user ID and purpose; recovery codes as HMAC with a key derived from it; sessions as SHA-256 of the cookie.
Index ¶
- Constants
- Variables
- func CSRF(next http.Handler, sessionToken func(*http.Request) (string, bool)) http.Handler
- func CheckPassword(username, password string) error
- func CheckUsername(name string) error
- func ClearSessionCookie() *http.Cookie
- func ClientIP(r *http.Request, trusted []netip.Prefix) netip.Addr
- func CreateKeyFile(path string, rnd io.Reader) error
- func DeviceCookie(value string) *http.Cookie
- func SafeMethod(m string) bool
- func SameCSRFToken(got, want string) bool
- func SessionCookie(token string) *http.Cookie
- func WriteEnrollmentFile(path string, e *Enrollment) (err error)
- type Client
- type Draft
- type Enrollment
- type Hasher
- type Key
- type LockedError
- type LoginResult
- type NewUserRequest
- type Params
- type Passkey
- type Passkeys
- type PolicyError
- type RefusedError
- type Service
- func (s *Service) Authenticate(ctx context.Context, token string) (*Session, error)
- func (s *Service) AuthenticatePassive(ctx context.Context, token string) (*Session, error)
- func (s *Service) AuthenticateToken(ctx context.Context, secret string) (*Session, error)
- func (s *Service) BeginPasskeyLogin(ctx context.Context, token string, c Client) (json.RawMessage, error)
- func (s *Service) BeginPasskeyRegistration(ctx context.Context, token, currentPassword, ip string) (json.RawMessage, error)
- func (s *Service) ChangePassword(ctx context.Context, token, current, next, ip string) error
- func (s *Service) ConfirmTOTP(ctx context.Context, userID, code string, who keys.Who) error
- func (s *Service) ConfirmTOTPChange(ctx context.Context, token, code, ip string) error
- func (s *Service) CreateToken(ctx context.Context, token, name string, roles []authz.Binding, ...) (string, *Token, error)
- func (s *Service) CreateUser(ctx context.Context, req NewUserRequest) (*Enrollment, error)
- func (s *Service) DeletePasskey(ctx context.Context, token, passkeyID, currentPassword, ip string) error
- func (s *Service) DisableUser(ctx context.Context, userID string, who keys.Who) error
- func (s *Service) EnableUser(ctx context.Context, userID string, who keys.Who) error
- func (s *Service) FinishPasskeyLogin(ctx context.Context, token string, body []byte, c Client) (*LoginResult, error)
- func (s *Service) FinishPasskeyRegistration(ctx context.Context, token, name string, body []byte, ip string) (*Passkey, error)
- func (s *Service) HasPasskeys(ctx context.Context, userID string) (bool, error)
- func (s *Service) ListPasskeys(ctx context.Context, token string) ([]Passkey, error)
- func (s *Service) ListTokens(ctx context.Context, token string) ([]Token, error)
- func (s *Service) ListUsers(ctx context.Context, who keys.Who) ([]UserInfo, error)
- func (s *Service) Login(ctx context.Context, username, password, ip string) (*LoginResult, error)
- func (s *Service) LoginFrom(ctx context.Context, username, password string, c Client) (*LoginResult, error)
- func (s *Service) LoginRecoveryCode(ctx context.Context, pendingToken, code, ip string) (*LoginResult, error)
- func (s *Service) LoginTOTP(ctx context.Context, pendingToken, code, ip string) (*LoginResult, error)
- func (s *Service) Logout(ctx context.Context, token, ip string) error
- func (s *Service) NewDraft(username string) (*Draft, error)
- func (s *Service) NewRecoveryCodes(ctx context.Context, token, currentPassword, ip string) ([]string, error)
- func (s *Service) PruneSessions(ctx context.Context) (int64, error)
- func (s *Service) RemoveRole(ctx context.Context, userID, tenant, ca string, who keys.Who) error
- func (s *Service) ResetTOTP(ctx context.Context, username string, who keys.Who) (*Enrollment, error)
- func (s *Service) RevokeToken(ctx context.Context, token, id, ip string) error
- func (s *Service) SecondFactor(ctx context.Context, pendingToken, code string, c Client) (*LoginResult, error)
- func (s *Service) SetRole(ctx context.Context, userID string, b authz.Binding, who keys.Who) error
- func (s *Service) SetRoles(ctx context.Context, userID, tenant string, want []authz.Binding, who keys.Who) error
- func (s *Service) StartTOTPChange(ctx context.Context, token, currentPassword, ip string) (*Enrollment, error)
- func (s *Service) StepUp(ctx context.Context, token, code, ip string) (*Session, error)
- func (s *Service) StepUpFrom(ctx context.Context, token, code string, c Client) (*Session, error)
- func (s *Service) Unlock(ctx context.Context, username string, who keys.Who) error
- func (s *Service) UnlockByID(ctx context.Context, userID string, who keys.Who) error
- func (s *Service) UserByID(ctx context.Context, who keys.Who, id string) (*UserInfo, error)
- type Session
- type SessionBinding
- type Throttle
- func (t *Throttle) DeviceLocked(nonce string, now time.Time) bool
- func (t *Throttle) Failure(ip, user string, known bool, now time.Time)
- func (t *Throttle) FailureDevice(ip, user, nonce string, now time.Time)
- func (t *Throttle) Forget(user string)
- func (t *Throttle) Success(ip, user string)
- func (t *Throttle) Wait(ip, user string, known bool, now time.Time) time.Duration
- func (t *Throttle) WaitDevice(ip, user string, now time.Time) time.Duration
- type Token
- type UserInfo
Constants ¶
const ( CSRFHeader = "X-CSRF-Token" CSRFField = "csrf_token" )
CSRF token transport: htmx sends the header (set from a <meta> tag), plain forms the hidden field.
const ( // DeviceCookieName is the cookie of a known device. DeviceCookieName = "__Host-myownpki_device" // DeviceCookieTTL: a device stays known this long after its last sign-in. DeviceCookieTTL = 365 * 24 * time.Hour // DeviceLockAfter failures with one device cookie lock that cookie for // DeviceLockFor; it then counts like an unknown browser. DeviceLockAfter = 10 DeviceLockFor = 15 * time.Minute )
const ( // MaxParallelHashes bounds the memory a login flood can take: // 4 x 64 MiB. The throttle refuses before a slot is taken. MaxParallelHashes = 4 // HashWait is how long a request waits for a free slot before "busy". HashWait = 2 * time.Second )
const ( MinPasswordRunes = 12 MaxPasswordRunes = 256 MaxUsername = 64 )
Password and user name rules (NIST SP 800-63B, PHASE1 step 10): length instead of composition rules, no expiry, a check against common passwords.
const ( LockAfter = 10 LockFor = 15 * time.Minute )
Lockout (the persistent stage after the in-memory throttle): after LockAfter failures in a row the account is locked for LockFor, then the count starts again. Never for good – otherwise anybody could lock the admin out by typing wrong passwords (myownpki user unlock ends it early).
const ( // PendingTTL: after the password, the second factor must follow within this time. PendingTTL = 5 * time.Minute // IdleTimeout ends a session nobody used for this long. IdleTimeout = 30 * time.Minute // AbsoluteTimeout ends every session, used or not. AbsoluteTimeout = 12 * time.Hour )
Session timing (PHASE1 step 10, owner decision e).
const ( TokenPrefix = "mop_" MaxTokens = 20 MaxTokenLife = 366 * 24 * time.Hour )
Token limits.
const CookieName = "__Host-myownpki_session"
CookieName has the __Host- prefix: the browser only accepts it with Secure, Path=/ and no Domain, so a sibling host can't set or overwrite it.
const (
MaxPasskeys = 10
)
Limits.
const (
// RecoveryCodeCount codes per user, each usable once.
RecoveryCodeCount = 10
)
const (
TOTPSecretSize = 20 // 160 bits, as RFC 4226 recommends
)
TOTP parameters (RFC 6238): the defaults every authenticator app understands (Aegis, Google, Microsoft, 1Password).
Variables ¶
var ( ErrPasskeysOff = errors.New("passkeys are not set up on this server (auth.passkey_origin)") ErrNoPasskey = errors.New("no passkey is registered for this user") ErrNoCeremony = errors.New("no passkey request is open for this session – start again") ErrTooManyPasskeys = fmt.Errorf("at most %d passkeys per user – remove one first", MaxPasskeys) )
Errors of the passkey ceremonies.
var ( ErrInvalidLogin = errors.New("wrong user name or password") ErrInvalidCode = errors.New("wrong or already used code") ErrLocked = errors.New("too many failed attempts") )
Errors. ErrInvalidLogin is the same for an unknown user, a wrong password and a disabled account: the answer doesn't tell which names exist.
var DefaultParams = Params{Time: 3, MemoryKiB: 64 * 1024, Threads: 1}
DefaultParams: 64 MiB, 3 passes, 1 lane – above the OWASP minimum (19 MiB, t=2). The unseal passphrase uses 256 MiB, but it is checked rarely; logins are frequent.
var ErrBadUsername = errors.New("user name: 1 to 64 characters, lower case a-z, digits and . _ @ -, starting with a letter or digit")
ErrBadUsername: user names are refused, never converted.
var ErrBusy = errors.New("the server is busy – try again in a moment")
ErrBusy: all hash slots are taken – the client should retry shortly.
var ErrCSRF = errors.New("missing or wrong CSRF token – reload the page")
ErrCSRF: a state-changing request without the session's token.
var ErrEnrollmentNeedsFile = errors.New("standard output is not an interactive terminal – " +
"the TOTP secret and recovery codes would end up in a log; use --otpauth-file <path>")
ErrEnrollmentNeedsFile: without an interactive terminal (Docker, systemd, a pipe) the secret would end up in a log, so it may only go to a file.
var ErrKeyExists = errors.New("the auth key file exists already – it is never overwritten")
ErrKeyExists: an auth key is never overwritten – every TOTP secret would become unreadable.
var ErrNoSession = errors.New("not signed in or the session has ended – sign in again")
ErrNoSession: no valid session – sign in (again).
var ErrNoTOTPChange = errors.New("no authenticator change was started")
ErrNoTOTPChange: confirm without a started change.
var ErrNoToken = errors.New("no such API token")
ErrNoToken: no such token of this user.
var ErrNoUser = errors.New("no such user")
ErrNoUser: no user with this ID.
var ErrRefused = errors.New("request refused")
ErrRefused is wrapped by *RefusedError: a request the caller can fix.
var ErrUnreadableSecret = errors.New("the TOTP secret can't be read with this auth key – wrong auth.key_file? (lost key: myownpki user reset-2fa)")
ErrUnreadableSecret: the TOTP secret doesn't open with this auth key – another key file, or a damaged row.
var ErrWeakPassword = errors.New("password refused")
ErrWeakPassword is wrapped by every *PolicyError.
Functions ¶
func CSRF ¶
CSRF protects state-changing requests in two layers (security.md):
- http.CrossOriginProtection refuses cross-origin requests by the browser's Sec-Fetch-Site / Origin headers – this also covers the login form, which has no session yet;
- a request with a session must carry the session's token (header or form field), compared in constant time.
sessionToken returns the expected token of the request's session, or false when the request has none. GET, HEAD and OPTIONS pass unchecked: they must not change state.
func CheckPassword ¶
CheckPassword applies the password rules for username.
func CheckUsername ¶
CheckUsername applies the user name rule. Upper case is refused, not lowered: the name a user types is the name that is stored.
func ClearSessionCookie ¶
ClearSessionCookie removes the cookie (logout).
func ClientIP ¶
ClientIP returns the address of the client behind r. Without trusted proxies it is the direct peer. When the peer is a trusted proxy, the X-Forwarded-For list is read from the right: the first address that is not a trusted proxy is the client. Everything left of it was written by the client itself and is never believed.
func CreateKeyFile ¶
CreateKeyFile writes a new random auth key to path (mode 0600). It never overwrites an existing file. rnd nil = crypto/rand.
func DeviceCookie ¶
DeviceCookie is the cookie for value (from LoginResult.DeviceCookie).
func SafeMethod ¶
SafeMethod: GET, HEAD and OPTIONS must not change state and need no token.
func SameCSRFToken ¶
SameCSRFToken compares a sent token with the session's in constant time; an empty expected token never matches.
func SessionCookie ¶
SessionCookie is the cookie for token. No Expires: the browser drops it at exit, the server ends it after IdleTimeout / AbsoluteTimeout anyway.
func WriteEnrollmentFile ¶
func WriteEnrollmentFile(path string, e *Enrollment) (err error)
WriteEnrollmentFile writes e to a new file with mode 0600 – for setups without a terminal (Docker demo). An existing file is never overwritten.
Types ¶
type Client ¶
type Client struct {
IP string
// Device is the value of the device cookie; "" = none.
Device string
}
Client is where a sign-in attempt comes from.
type Draft ¶
type Draft struct {
// Enrollment to show or write; UserID is filled in by CreateUser.
Enrollment *Enrollment
// contains filtered or unexported fields
}
Draft is the second factor of a user who doesn't exist yet: TOTP secret and recovery codes made before anything is written. init shows it and takes the first code before it writes (owner decision f), and a setup without a terminal writes its files first – nothing in the database refers to a secret that was never handed out.
func (*Draft) Clear ¶
func (d *Draft) Clear()
Clear removes the secret from memory once it is stored and shown.
type Enrollment ¶
type Enrollment struct {
UserID string
Username string
// URI is the otpauth:// link (QR code or a file for the Docker demo).
URI string
// Secret is the same secret for typing in, in groups of four.
Secret string
// RecoveryCodes, when new ones were made (user creation, reset-2fa).
RecoveryCodes []string
}
Enrollment is what a user needs to set up an authenticator app. Show it once; it is never shown again.
func (*Enrollment) Text ¶
func (e *Enrollment) Text() string
Text is the enrollment for a person: what to do, the link, the secret and the recovery codes.
type Hasher ¶
type Hasher struct {
// contains filtered or unexported fields
}
Hasher hashes and checks passwords with a bounded number of parallel runs.
type Key ¶
type Key struct {
// contains filtered or unexported fields
}
Key is the auth key. It lives outside the databases, so a copy of system.db alone holds no usable TOTP secret.
type LockedError ¶
LockedError carries how long the caller must wait (HTTP 429 Retry-After).
func (*LockedError) Error ¶
func (e *LockedError) Error() string
func (*LockedError) Unwrap ¶
func (e *LockedError) Unwrap() error
type LoginResult ¶
type LoginResult struct {
// Token is the new cookie value (SessionCookie). After the password it is
// a pending session; after the second factor a full one.
Token string
Session *Session
// NeedsSecondFactor: the password was right, a TOTP code (or a recovery
// code) must follow.
NeedsSecondFactor bool
// FirstTOTP: the authenticator was never confirmed – the setup from init
// or reset-2fa is completed by this login.
FirstTOTP bool
// Factor is the second factor used: "totp" or "recovery_code".
Factor string
// RecoveryCodesLeft after a sign-in with a recovery code.
RecoveryCodesLeft int
// DeviceCookie is a new device cookie value after a complete sign-in
// (DeviceCookie); renewed at every one.
DeviceCookie string
Warnings []string
}
LoginResult is the outcome of a sign-in step.
type NewUserRequest ¶
type NewUserRequest struct {
Username string
Password string
InstanceAdmin bool
Roles []authz.Binding
// Draft, if set, is the second factor made beforehand (init); nil = a
// new secret and new recovery codes.
Draft *Draft
Who keys.Who
}
NewUserRequest creates a user with password, TOTP secret and recovery codes. Who needs user.manage (init runs as the console).
type Params ¶
Params are the Argon2id parameters of a password hash. They are stored in the hash (PHC string format), so stronger defaults apply to old hashes at the next sign-in.
func TestParams ¶ added in v0.2.0
func TestParams() Params
TestParams are the weak Argon2id parameters of tests – the same values as the key ring's test KDF, kept in one place (keys.TestArgon2). It panics outside a test binary.
type Passkeys ¶
type Passkeys struct {
// RPID is the host name passkeys are bound to.
RPID string
// contains filtered or unexported fields
}
Passkeys holds the WebAuthn relying party and the open ceremonies.
func NewPasskeys ¶
NewPasskeys sets up the relying party for rpID and origin (both from config.PasskeyRPID and auth.passkey_origin).
type PolicyError ¶
type PolicyError struct{ Reasons []string }
PolicyError lists every rule a password breaks.
func (*PolicyError) Error ¶
func (e *PolicyError) Error() string
func (*PolicyError) Unwrap ¶
func (e *PolicyError) Unwrap() error
type RefusedError ¶
type RefusedError struct{ Reasons []string }
RefusedError lists every problem of a user management request at once.
func (*RefusedError) Error ¶
func (e *RefusedError) Error() string
func (*RefusedError) Unwrap ¶
func (e *RefusedError) Unwrap() error
type Service ¶
type Service struct {
System *sql.DB // writer of system.db
Audit *sql.DB // writer of the instance audit log (<data>/audit.db)
Key *Key
Hasher *Hasher
Throttle *Throttle
Clock clock.Clock
Tenant string // tenant whose step-up setting new proofs snapshot
Rand io.Reader // nil = crypto/rand
// Issuer is the name authenticator apps show; "" = "MyOwnPKI".
Issuer string
// Wake, if set, is called after an audit event was written to the outbox.
Wake func()
// Passkeys is the WebAuthn relying party; nil = no passkeys (TOTP only).
Passkeys *Passkeys
}
Service signs users in and manages their sessions and second factors.
func NewService ¶
NewService returns a service with the production hasher and throttle.
func (*Service) Authenticate ¶
Authenticate returns the signed-in session of token with its principal. It ends sessions of disabled users and records activity (at most once a minute), which moves the idle timeout.
func (*Service) AuthenticatePassive ¶
AuthenticatePassive is Authenticate without counting as activity: for requests a page makes on its own (status polling), so an open browser tab still times out (owner 2026-10-17).
func (*Service) AuthenticateToken ¶
AuthenticateToken turns a bearer secret into a session-like principal: the token's roles that the owner still has, no instance admin, no step-up. Expired tokens and tokens of disabled users don't work.
func (*Service) BeginPasskeyLogin ¶
func (s *Service) BeginPasskeyLogin(ctx context.Context, token string, c Client) (json.RawMessage, error)
BeginPasskeyLogin starts an assertion: after the password (pending session) it is the second factor, while signed in it is a step-up.
func (*Service) BeginPasskeyRegistration ¶
func (s *Service) BeginPasskeyRegistration(ctx context.Context, token, currentPassword, ip string) (json.RawMessage, error)
BeginPasskeyRegistration starts adding a passkey: it needs a fresh step-up (checked by the caller with authz) and the current password (decision 45). The options go unchanged to navigator.credentials.create().
func (*Service) ChangePassword ¶
ChangePassword sets a new password; it needs the current one. Every other session of the user ends.
func (*Service) ConfirmTOTP ¶
ConfirmTOTP confirms the authenticator of a new user right away (init on the console asks for the first code).
func (*Service) ConfirmTOTPChange ¶
ConfirmTOTPChange switches to the new secret once a code from it works. Every other session of the user ends.
func (*Service) CreateToken ¶
func (s *Service) CreateToken(ctx context.Context, token, name string, roles []authz.Binding, expires time.Time, ip string) (string, *Token, error)
CreateToken makes a token for the signed-in user with roles the user has (never more) and an end within a year. The secret is returned once.
func (*Service) CreateUser ¶
func (s *Service) CreateUser(ctx context.Context, req NewUserRequest) (*Enrollment, error)
CreateUser stores the user and returns the enrollment to show once: the TOTP secret is fixed now, so the first code – at init on the console, or at the first login – only confirms it (no window in which somebody else could set up their own authenticator).
func (*Service) DeletePasskey ¶
func (s *Service) DeletePasskey(ctx context.Context, token, passkeyID, currentPassword, ip string) error
DeletePasskey removes one of the signed-in user's passkeys; it needs the current password (and a fresh step-up, checked by the caller).
func (*Service) DisableUser ¶
DisableUser disables a user for good (users are never deleted: their ID is in the audit log) and ends their sessions. Nobody disables themselves.
func (*Service) EnableUser ¶
EnableUser lets a disabled user sign in again.
func (*Service) FinishPasskeyLogin ¶
func (s *Service) FinishPasskeyLogin(ctx context.Context, token string, body []byte, c Client) (*LoginResult, error)
FinishPasskeyLogin checks the assertion. For a pending session it completes the sign-in (a new session ID, like a TOTP code); while signed in it refreshes the step-up time. A wrong assertion counts like a wrong code; a sign counter that goes back is refused as a cloned authenticator.
func (*Service) FinishPasskeyRegistration ¶
func (s *Service) FinishPasskeyRegistration(ctx context.Context, token, name string, body []byte, ip string) (*Passkey, error)
FinishPasskeyRegistration stores the passkey the browser created. The credentials epoch rises (device cookies void) and the user's other sessions end, as for every new authenticator.
func (*Service) HasPasskeys ¶
HasPasskeys tells whether a sign-in may offer the passkey method.
func (*Service) ListPasskeys ¶
ListPasskeys lists the passkeys of the signed-in user.
func (*Service) ListTokens ¶
ListTokens lists the signed-in user's tokens.
func (*Service) LoginFrom ¶
func (s *Service) LoginFrom(ctx context.Context, username, password string, c Client) (*LoginResult, error)
LoginFrom is Login with the client's device cookie: a known device is judged by its own counter instead of the user lockout.
func (*Service) LoginRecoveryCode ¶
func (s *Service) LoginRecoveryCode(ctx context.Context, pendingToken, code, ip string) (*LoginResult, error)
LoginRecoveryCode completes a sign-in with a recovery code (lost phone). Each code works once.
func (*Service) LoginTOTP ¶
func (s *Service) LoginTOTP(ctx context.Context, pendingToken, code, ip string) (*LoginResult, error)
LoginTOTP completes a sign-in with a TOTP code. The pending session is replaced by a new full one: a new session ID after every privilege change.
func (*Service) NewRecoveryCodes ¶
func (s *Service) NewRecoveryCodes(ctx context.Context, token, currentPassword, ip string) ([]string, error)
NewRecoveryCodes replaces all recovery codes of the signed-in user; it needs the current password. Show the codes once.
func (*Service) PruneSessions ¶
PruneSessions deletes ended sessions; the server runs it periodically.
func (*Service) RemoveRole ¶
RemoveRole takes a role away; the user's sessions end.
func (*Service) ResetTOTP ¶
func (s *Service) ResetTOTP(ctx context.Context, username string, who keys.Who) (*Enrollment, error)
ResetTOTP gives a user a new TOTP secret and new recovery codes and ends their sessions. The user confirms the secret at the next login – only this secret works, so there is no window for anybody else. Used by admins and by myownpki user reset-2fa (lost phone, lost auth key).
func (*Service) RevokeToken ¶
RevokeToken deletes one of the signed-in user's tokens; it stops working at once.
func (*Service) SecondFactor ¶
func (s *Service) SecondFactor(ctx context.Context, pendingToken, code string, c Client) (*LoginResult, error)
SecondFactor completes a sign-in with what the user typed: six digits are a TOTP code, anything else is tried as a recovery code. Failures of both count in the same throttle and lockout as wrong passwords.
func (*Service) SetRole ¶
SetRole gives a user a role in a tenant (optionally one CA). The user's sessions end: new rights only with a new session (security.md).
func (*Service) SetRoles ¶
func (s *Service) SetRoles(ctx context.Context, userID, tenant string, want []authz.Binding, who keys.Who) error
SetRoles replaces the roles of a user in one tenant: missing ones are added, others removed. The user's sessions end (by SetRole/RemoveRole).
func (*Service) StartTOTPChange ¶
func (s *Service) StartTOTPChange(ctx context.Context, token, currentPassword, ip string) (*Enrollment, error)
StartTOTPChange creates a new authenticator secret for the signed-in user; it needs the current password. The old secret stays valid until ConfirmTOTPChange.
func (*Service) StepUp ¶
StepUp confirms a sensitive action with a fresh TOTP code (security.md): the session snapshots the proof time and the tenant's current lifetime.
func (*Service) StepUpFrom ¶
StepUpFrom is StepUp with the client's device cookie.
func (*Service) UnlockByID ¶
UnlockByID ends a lockout early, like `myownpki user unlock`.
type Session ¶
type Session struct {
UserID string
Username string
CSRFToken string
CreatedAt time.Time
ExpiresAt time.Time // absolute end (a pending session: PendingTTL)
LastSeen time.Time // last activity; the idle timeout counts from here
StepUpAt time.Time
StepUpDuration time.Duration
// Principal is what the session may do; nil for a pending session.
Principal *authz.Principal
// TokenID and TokenName are set when an API token signed the request in
// (no cookie, no CSRF token, never a step-up).
TokenID, TokenName string
// contains filtered or unexported fields
}
Session is a signed-in user (or one between password and second factor).
func (*Session) Binding ¶ added in v0.3.1
func (s *Session) Binding() SessionBinding
Binding returns the immutable binding of this authenticated session.
func (*Session) IdleExpiresAt ¶
IdleExpiresAt is when the session ends without further activity.
type SessionBinding ¶ added in v0.3.1
SessionBinding identifies the server-side session and the user's credentials generation without exposing either as mutable Session fields.
type Throttle ¶
type Throttle struct {
// contains filtered or unexported fields
}
Throttle slows down guessing of passwords, TOTP and recovery codes. It lives in memory and is checked before any hash is computed. The lockout in the database (users.locked_until) is the second, persistent stage.
func (*Throttle) DeviceLocked ¶
DeviceLocked reports whether the device cookie with this random value had too many failures: it then counts like an unknown browser.
func (*Throttle) FailureDevice ¶
FailureDevice counts a failed attempt with a device cookie: against (IP, user) and against the cookie, not against the user.
func (*Throttle) Success ¶
Success clears the strict counter of (ip, user). The per-user counter stays: a successful login of the real user must not reset what an attacker elsewhere has built up.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package passkeytest is a virtual WebAuthn authenticator for tests (PHASE1 step 17): it answers the options of navigator.credentials.create() and .get() the way a browser with a platform authenticator does – ECDSA P-256, attestation "none", user verification done.
|
Package passkeytest is a virtual WebAuthn authenticator for tests (PHASE1 step 17): it answers the options of navigator.credentials.create() and .get() the way a browser with a platform authenticator does – ECDSA P-256, attestation "none", user verification done. |