auth

package
v0.0.0-...-393e165 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: AGPL-3.0 Imports: 45 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OPAQUE_USER_RECORD_LEN         = 256
	OPAQUE_SHARED_SECRETBYTES      = 64
	OPAQUE_REGISTRATION_RECORD_LEN = 192
	OPAQUE_USER_SESSION_PUBLIC_LEN = 96
	OPAQUE_USER_SESSION_SECRET_LEN = 226
	OPAQUE_SERVER_SESSION_LEN      = 320

	// Multi-step registration constants
	OPAQUE_REGISTER_USER_SEC_LEN = 34 // 32 (r) + 2 (pwdU_len)
	OPAQUE_REGISTER_REQUEST_LEN  = 32 // crypto_core_ristretto255_BYTES (blinded element M)
	OPAQUE_REGISTER_PUBLIC_LEN   = 64 // 32 (Z) + 32 (pkS) - server response
	OPAQUE_REGISTER_SECRET_LEN   = 64 // 32 (skS) + 32 (kU)
)

OPAQUE protocol constants from libopaque

View Source
const (
	EnvelopeRotationMandatePurpose = "envelope-master-rotation"
	EnvelopeRotationMandateTTL     = 10 * time.Minute
)
View Source
const (
	AudienceMFA            = "arkfile-mfa"
	AudienceAPI            = "arkfile-api"
	AudienceExport         = "arkfile-export"
	AudienceReset          = "arkfile-mfa-reset"
	AudienceReregistration = "arkfile-reregistration"
	Issuer                 = "arkfile-auth"
)

JWT audience constants. These are checked at the validator (ParseTokenFunc) in addition to the per-tier signing-key separation.

View Source
const (
	MFAMethodTOTP     = "totp"
	MFAMethodWebAuthn = "webauthn"
)
View Source
const (
	TOTPIssuer       = "Arkfile"
	TOTPDigits       = 6
	TOTPPeriod       = 30
	TOTPSkew         = 1 // Allow ±1 window (accepts current, previous, and next 30s windows)
	BackupCodeLength = 10
	BackupCodeCount  = 10
)
View Source
const (
	OpaqueServerPrivateKeyID = "opaque_server_private_key"
	OpaqueOPRFSeedKeyID      = "opaque_oprf_seed"
	OpaqueKeyType            = "opaque"
)

Opaque server key ids in system_keys (shared with rotation tooling).

View Source
const (
	UserSecretRotationMandatePurpose = "user-secret-master-rotation"
	UserSecretRotationMandateTTL     = 10 * time.Minute
)
View Source
const BackupCodeCharset = "ACDEFGHJKLMNPQRTUVWXY34679"

Human-friendly backup code character set (excludes B/8, O/0, I/1, S/5, Z/2)

View Source
const DefaultOpaqueServerID = "localhost"

DefaultOpaqueServerID is the OPAQUE server identity (idS) used when no deployment domain is resolved. Config normally always sets Server.Domain (ARKFILE_DOMAIN, else BASE_URL host, else "localhost"), so this is a defensive fallback that matches the config-level "localhost" default to keep local and dev deployments authenticating deterministically.

Variables

View Source
var BootstrapTokenPath = "/opt/arkfile/etc/keys/bootstrap-token.bin"

BootstrapTokenPath is the on-disk delivery channel for the bootstrap token.

The token MUST NOT be logged to stdout or journald, because any operator or attacker with `journalctl` access on the host would otherwise be able to harvest it. Instead, CheckAndGenerateBootstrapToken writes the hex-encoded token to this file (mode 0400, owned by the arkfile process user) and the operator reads it back with `sudo cat`.

Tests override this via a package-private setter to point at a temp file.

View Source
var Echo *echo.Group

Echo is the Echo group with authentication middleware applied

Functions

func ActiveJWTKeyIDs

func ActiveJWTKeyIDs() (tempKeyID, fullKeyID string, err error)

ActiveJWTKeyIDs returns the system_keys key ids of the active temp and full signing versions. Useful for health monitoring that must follow rotation.

func ActiveJWTKeyVersions

func ActiveJWTKeyVersions() (tempVersion, fullVersion int, err error)

ActiveJWTKeyVersions reports the active signing version of each tier.

func ApplyEnvelopeMasterRotation

func ApplyEnvelopeMasterRotation(opts ApplyEnvelopeMasterRotationOptions) (crypto.EnvelopeRotationStats, error)

ApplyEnvelopeMasterRotation performs mandate-gated envelope master key rotation. With the service stopped it re-wraps every system_keys row under a freshly generated master (regenerating the EntityID master), writes the new master to a root-only recovery file before committing so it can never be lost, backs up secrets.env, swaps in the new ARKFILE_MASTER_KEY value, and verifies the whole table decrypts under the new master.

func ApplyUserSecretMasterRotation

func ApplyUserSecretMasterRotation(opts ApplyUserSecretMasterRotationOptions) (crypto.UserSecretRotationStats, error)

ApplyUserSecretMasterRotation performs mandate-gated user-secret master rotation with DB re-encryption.

func CanDecryptMFASecret

func CanDecryptMFASecret(db *sql.DB, username string) (present bool, decryptable bool, enabled bool, setupCompleted bool, err error)

CanDecryptMFASecret checks whether a user's MFA credential blob decrypts (dev diagnostic helper).

func CheckAndGenerateBootstrapToken

func CheckAndGenerateBootstrapToken(db *sql.DB) error

CheckAndGenerateBootstrapToken checks if the system needs bootstrapping. Bootstrap mode is enabled when: 1. No ACTIVE admin users exist (users with last_login set), OR 2. ARKFILE_FORCE_ADMIN_BOOTSTRAP environment variable is set to "true"

This function is safe for multi-instance deployments - it checks if a bootstrap token already exists before generating a new one, preventing multiple tokens from being written.

The token is delivered to the operator via the on-disk file at BootstrapTokenPath (mode 0400). The token is NEVER logged to stdout or the systemd journal.

func CleanupExpiredSessions

func CleanupExpiredSessions(db *sql.DB) error

CleanupExpiredSessions removes all expired sessions

func CleanupExpiredTokens

func CleanupExpiredTokens(db *sql.DB) error

CleanupExpiredTokens removes expired per-JTI entries from revoked_tokens.

func CleanupMFALogs

func CleanupMFALogs(db *sql.DB) error

CleanupMFALogs removes old MFA usage and backup-code replay logs.

func ClearWebAuthnSessionsForUser

func ClearWebAuthnSessionsForUser(username string)

ClearWebAuthnSessionsForUser removes any in-flight ceremony state for a user.

func ClientCreateCredentialRequest

func ClientCreateCredentialRequest(password []byte) ([]byte, []byte, error)

ClientCreateCredentialRequest creates the initial authentication request This is Step 1 of the authentication flow (client-side) Input: password (user's password) Output: sec (client secret to store), pub (credential request to send to server)

func ClientCreateRegistrationRequest

func ClientCreateRegistrationRequest(password []byte) ([]byte, []byte, error)

ClientCreateRegistrationRequest creates the initial registration request This is Step 1 of the registration flow (client-side) Input: password (user's password) Output: usrCtx (client context to store), M (registration request to send to server)

func ClientFinalizeRegistration

func ClientFinalizeRegistration(usrCtx []byte, serverResponse []byte, username string, serverID string) ([]byte, []byte, error)

ClientFinalizeRegistration finalizes the registration process This is Step 3 of the registration flow (client-side) Input: usrCtx (client context from step 1), serverResponse (rpub from server), username, and serverID (idS, fetched from the server's /api/config/opaque so it matches the server's OPAQUE transcript exactly). Output: rrec (registration record to send to server), exportKey (client export key)

func ClientRecoverCredentials

func ClientRecoverCredentials(sec []byte, serverResponse []byte, username string, serverID string) ([]byte, []byte, []byte, error)

ClientRecoverCredentials recovers credentials from server response This is Step 3 of the authentication flow (client-side) Input: sec (client secret from step 1), serverResponse (credential response from server), username, and serverID (idS, fetched from /api/config/opaque so it matches the server's OPAQUE transcript exactly). Output: sk (session key), authU (authentication token to send to server), exportKey (client export key)

func CompleteMFASetup

func CompleteMFASetup(db *sql.DB, username, testCode string) error

CompleteMFASetup validates a test code and enables MFA for the user.

func ConsumeEnvelopeRotationMandate

func ConsumeEnvelopeRotationMandate(db *sql.DB, nonce string) error

ConsumeEnvelopeRotationMandate marks a mandate nonce as used.

func ConsumeUserSecretRotationMandate

func ConsumeUserSecretRotationMandate(db *sql.DB, nonce string) error

ConsumeUserSecretRotationMandate marks a mandate nonce as used.

func CreateAuthSession

func CreateAuthSession(db *sql.DB, username string, flowType string, serverPublicKey []byte) (string, error)

CreateAuthSession creates a new authentication session for multi-step protocol

func CreateCredentialResponse

func CreateCredentialResponse(credentialRequest []byte, userRecord []byte, username string) ([]byte, []byte, error)

CreateCredentialResponse handles server-side step of authentication Takes client's credential request (pub), user record (rec), and username, returns server response

func CreateDevAdminWithOPAQUE

func CreateDevAdminWithOPAQUE(db *sql.DB, username, password string) (*models.User, error)

CreateDevAdminWithOPAQUE creates a dev admin user with OPAQUE registration This function simulates the complete client-server OPAQUE registration flow internally to create a dev admin user with known credentials for testing.

CRITICAL SECURITY: This function has triple-layer protection: 1. Production environment check 2. Exact username validation (only "arkfile-dev-admin") 3. ADMIN_USERNAMES environment variable verification

func CreateRegistrationResponse

func CreateRegistrationResponse(requestData []byte) ([]byte, []byte, error)

CreateRegistrationResponse handles server-side step of registration Takes client's registration request (M) and returns server response (rpub) and secret (rsec)

func DeleteAllRefreshTokensForUser

func DeleteAllRefreshTokensForUser(db *sql.DB, username string) error

func DeleteAuthSession

func DeleteAuthSession(db *sql.DB, sessionID string) error

DeleteAuthSession removes a session after use

func DeriveFakeUserRecord

func DeriveFakeUserRecord(username string) ([]byte, error)

DeriveFakeUserRecord deterministically generates a fake 256-byte OPAQUE user record for a non-existent username

func GenerateFullAccessToken

func GenerateFullAccessToken(username string) (string, time.Time, error)

GenerateFullAccessToken creates a full access JWT token after MFA validation. Signed with the full-tier key; carries aud=arkfile-api and requires_mfa=false. Valid at every JWTMiddleware-protected route.

func GenerateRefreshToken

func GenerateRefreshToken() (string, error)

GenerateRefreshToken creates a cryptographically secure random string to be used as a refresh token. It aims for approximately 256 bits of entropy.

func GenerateReregistrationToken

func GenerateReregistrationToken(username string) (string, time.Time, error)

GenerateReregistrationToken creates a short-lived handoff token that authorizes only the OPAQUE re-registration ceremony for the named user. Signed with the temp-tier key; carries aud=arkfile-reregistration. Issued when a login lands on an account an operator has flagged for OPAQUE credential rotation.

func GenerateTemporaryMFAToken

func GenerateTemporaryMFAToken(username string) (string, time.Time, error)

GenerateTemporaryMFAToken creates a temporary JWT token that requires MFA completion. Signed with the temp-tier key; carries aud=arkfile-mfa and requires_mfa=true. Only valid at /api/mfa/{setup,verify,auth} via MFAJWTMiddleware.

func GenerateTemporaryResetToken

func GenerateTemporaryResetToken(username string) (string, time.Time, error)

GenerateTemporaryResetToken creates a short-lived reset-authorized temporary JWT token. Signed with the temp-tier key; carries aud=arkfile-mfa-reset.

func GetJWTFullPrivateKey

func GetJWTFullPrivateKey() ed25519.PrivateKey

GetJWTFullPrivateKey returns the active Ed25519 private key for full tokens.

func GetJWTFullPublicKey

func GetJWTFullPublicKey() ed25519.PublicKey

GetJWTFullPublicKey returns the active Ed25519 public key for full tokens.

func GetJWTFullVerificationKeys

func GetJWTFullVerificationKeys() []ed25519.PublicKey

GetJWTFullVerificationKeys returns every full-tier public key currently accepted for verification, active version first.

func GetJWTTempPrivateKey

func GetJWTTempPrivateKey() ed25519.PrivateKey

GetJWTTempPrivateKey returns the active Ed25519 private key for temp tokens.

func GetJWTTempPublicKey

func GetJWTTempPublicKey() ed25519.PublicKey

GetJWTTempPublicKey returns the active Ed25519 public key for temp tokens.

func GetJWTTempVerificationKeys

func GetJWTTempVerificationKeys() []ed25519.PublicKey

GetJWTTempVerificationKeys returns every temp-tier public key currently accepted for verification, active version first.

func GetOPAQUEServer

func GetOPAQUEServer() (bool, error)

GetOPAQUEServer returns a simple status check for libopaque server readiness

func GetPendingMFAMethodType

func GetPendingMFAMethodType(db *sql.DB, username string) (string, error)

GetPendingMFAMethodType returns method_type for an in-progress enrollment row.

func GetServerPrivateKey

func GetServerPrivateKey() ([]byte, error)

GetServerPrivateKey returns the server's OPAQUE private key. libopaque derives the matching public key from this private key during the protocol, so there is no separate stored public key.

func GetUserMFAMethodType

func GetUserMFAMethodType(db *sql.DB, username string) (string, error)

GetUserMFAMethodType returns the enrolled method_type for a user with completed MFA. Returns empty string when MFA is not enabled or no row exists.

func GetUsernameFromToken

func GetUsernameFromToken(c echo.Context) string

func GetWebAuthn

func GetWebAuthn() (*webauthn.WebAuthn, error)

GetWebAuthn returns the shared WebAuthn relying-party instance.

func HashToken

func HashToken(token string) (string, error)

HashToken generates a SHA-256 hash of a token string. The raw token should not be stored; only its hash.

func InvalidateUserRevocationCache

func InvalidateUserRevocationCache(username string)

InvalidateUserRevocationCache removes a user's cached entry so the next request re-reads from the DB. Call after writing user_jwt_revocations.

func IsOPAQUEAvailable

func IsOPAQUEAvailable() bool

IsOPAQUEAvailable checks if OPAQUE operations are available

func IsRevoked

func IsRevoked(db *sql.DB, tokenID string) (bool, error)

IsRevoked checks if a token has been revoked

func IsUserMFAEnabled

func IsUserMFAEnabled(db *sql.DB, username string) (bool, error)

IsUserMFAEnabled reports whether the user has completed MFA enrollment.

func IssueEnvelopeRotationMandate

func IssueEnvelopeRotationMandate(db *sql.DB, adminUsername string) (mandate string, expiresAt time.Time, err error)

IssueEnvelopeRotationMandate records a single-use mandate and returns a signed blob for offline apply.

func IssueUserSecretRotationMandate

func IssueUserSecretRotationMandate(db *sql.DB, adminUsername string) (mandate string, expiresAt time.Time, err error)

IssueUserSecretRotationMandate records a single-use mandate and returns a signed blob for offline apply.

func JWTMiddleware

func JWTMiddleware() echo.MiddlewareFunc

JWTMiddleware validates full-access tokens (aud=arkfile-api). It verifies the signature against the full-tier public key and enforces audience and issuer at the parser layer. A temp-tier token (signed with the temp key, aud=arkfile-mfa) fails here in two ways: wrong signing key AND wrong audience. Either is enough; both is defense in depth.

func LoadJWTFullKeys

func LoadJWTFullKeys() error

LoadJWTFullKeys ensures the full-tier key ring is loaded from system_keys.

func LoadJWTKeys

func LoadJWTKeys() error

LoadJWTKeys initializes both tiers. Kept for callers that just need to ensure the JWT subsystem is ready at startup.

func LoadJWTTempKeys

func LoadJWTTempKeys() error

LoadJWTTempKeys ensures the temp-tier key ring is loaded from system_keys.

func LoadWebAuthnSession

func LoadWebAuthnSession(username string, kind webAuthnSessionKind) (webauthn.SessionData, error)

LoadWebAuthnSession returns stored ceremony state and removes it (one-time use).

func MFAJWTMiddleware

func MFAJWTMiddleware() echo.MiddlewareFunc

MFAJWTMiddleware validates temporary MFA-handoff tokens (aud=arkfile-mfa). Used only by /api/mfa/{setup,verify,auth,recover-with-backup-code}. A full-tier token fails the signing-key check AND the audience check.

func MFAResetJWTMiddleware

func MFAResetJWTMiddleware() echo.MiddlewareFunc

MFAResetJWTMiddleware accepts either a full-tier token (aud=arkfile-api, requires_mfa=false) for self-service reset with a backup code, or a reset-tier token (aud=arkfile-mfa-reset) issued by recover-with-backup-code.

func MarshalWebAuthnOptions

func MarshalWebAuthnOptions(v interface{}) (json.RawMessage, error)

MarshalWebAuthnOptions JSON-encodes protocol options for API responses.

func OpaqueServerID

func OpaqueServerID() string

OpaqueServerID returns the OPAQUE server identity (idS) bound into the protocol transcript. It is the deployment domain when configured, otherwise DefaultOpaqueServerID. All OPAQUE participants (server, browser, CLI) must use the exact same value, so the browser and CLI fetch it from the server via GET /api/config/opaque rather than hardcoding it.

func ParseEdDSAClaimsAnyFullKey

func ParseEdDSAClaimsAnyFullKey(parser *jwt.Parser, tokenString string, claims jwt.Claims) (*jwt.Token, error)

ParseEdDSAClaimsAnyFullKey parses tokenString into the provided claims using the supplied parser, trying every full-tier verification key. Exposed for callers outside the auth package (e.g. export-token validation) that need rotation-aware verification with custom claim types. The parser should carry any required audience/issuer/expiry options.

func ReloadJWTKeys

func ReloadJWTKeys() error

ReloadJWTKeys reloads both tiers from system_keys, picking up any rotation (new active version, newly added or retired versions) without a restart.

func ReloadOpaqueServerKeys

func ReloadOpaqueServerKeys() error

ReloadOpaqueServerKeys reloads OPAQUE server key material from system_keys without a restart. Used after an operator replaces the server private key and OPRF seed during a deployment-wide rotation.

func RequireFullJWT

func RequireFullJWT(next echo.HandlerFunc) echo.HandlerFunc

RequireFullJWT is defense-in-depth: even though JWTMiddleware enforces the aud=arkfile-api audience, this middleware also asserts requires_mfa=false and re-verifies the audience claim. Protects against a future regression that loosens the validator's audience enforcement.

Wired onto every protected group: mfaProtectedGroup, pendingAllowedGroup, adminGroup, and devTestAdminGroup.

func RequiresMFAFromToken

func RequiresMFAFromToken(c echo.Context) bool

RequiresMFAFromToken returns whether the token in the request context carries the requires_mfa=true flag. Safe against missing/malformed context entries: returns false rather than panicking.

func ReregistrationJWTMiddleware

func ReregistrationJWTMiddleware() echo.MiddlewareFunc

ReregistrationJWTMiddleware validates the OPAQUE re-registration handoff token (aud=arkfile-reregistration). Used only by the re-registration ceremony endpoints. A missing, expired, or wrong-audience token yields a 401 that the ceremony handler maps to the reregistration_token_invalid contract code.

func ResetJWTMiddleware

func ResetJWTMiddleware() echo.MiddlewareFunc

ResetJWTMiddleware validates reset-authorized temporary tokens (aud=arkfile-mfa-reset). Used by /api/mfa/reset after backup-code recovery (path B).

func ResetKeysForTest

func ResetKeysForTest()

ResetKeysForTest clears the loaded key rings for testing purposes. DO NOT USE IN PRODUCTION.

func ResetOpaqueServerKeysForTest

func ResetOpaqueServerKeysForTest()

ResetOpaqueServerKeysForTest clears the in-memory OPAQUE keys. DO NOT USE IN PRODUCTION.

func RetireJWTKeyVersion

func RetireJWTKeyVersion(version int) error

RetireJWTKeyVersion removes a superseded signing key version from both tiers. It refuses to delete the currently active version of either tier. Call this only after the overlap window has elapsed (no unexpired token can still be signed under the retired version).

func RevokeAllUserJWTTokens

func RevokeAllUserJWTTokens(db *sql.DB, username, reason string) error

RevokeAllUserJWTTokens invalidates all full-tier JWTs issued before now for the user. Writes user_jwt_revocations (enforced by TokenRevocationMiddleware) and clears the in-process revocation cache so the next request sees the update.

func RevokeToken

func RevokeToken(db *sql.DB, tokenString, reason string) error

RevokeToken adds a token to the revocation list. Accepts either temp-tier or full-tier tokens so that /api/logout and /api/revoke-token work for any session state.

func SaveWebAuthnSession

func SaveWebAuthnSession(username string, kind webAuthnSessionKind, data *webauthn.SessionData) error

SaveWebAuthnSession stores ceremony state between begin and finish.

func SetupDevAdminTOTP

func SetupDevAdminTOTP(db *sql.DB, user *models.User, totpSecret string) error

SetupDevAdminTOTP sets up TOTP for the dev admin user with a fixed secret This allows predictable TOTP codes for testing purposes.

SECURITY: This function is protected by production environment checks

func SetupServerKeys

func SetupServerKeys(db *sql.DB) error

SetupServerKeys loads server key material from system_keys, generating it on first use. Safe for multi-instance deployments when combined with the KeyManager's insert-once semantics for initial key creation.

func StoreMFASetup

func StoreMFASetup(db *sql.DB, username string, setup *MFASetup) error

StoreMFASetup stores enrollment data with user-secret master encryption and hashed backup codes.

func StoreUserRecord

func StoreUserRecord(rsec []byte, rrec []byte) ([]byte, error)

StoreUserRecord finalizes registration by storing the user record Takes the server secret and client's finalized registration record, returns complete user record

func StoreWebAuthnPendingSetup

func StoreWebAuthnPendingSetup(db *sql.DB, username string, backupCodes []string) error

StoreWebAuthnPendingSetup creates a pending webauthn enrollment row with backup codes.

func TokenRevocationMiddleware

func TokenRevocationMiddleware(db *sql.DB) echo.MiddlewareFunc

TokenRevocationMiddleware checks tokens against both the per-JTI revocation list and the user-wide JWT revocation table. The user-wide check uses a 30-second in-process cache to avoid a DB round-trip on every request.

func UserAuth

func UserAuth(authUServer []byte, authUClient []byte) error

UserAuth validates the client's authentication token Takes server's authU and client's authU, returns true if they match

func ValidateAuthSession

func ValidateAuthSession(db *sql.DB, sessionID string, expectedFlowType string) (username string, serverPk []byte, err error)

ValidateAuthSession validates and retrieves session data

func ValidateBackupCode

func ValidateBackupCode(db *sql.DB, username, code string) error

ValidateBackupCode validates and consumes a hashed backup code (method-agnostic).

func ValidateBootstrapToken

func ValidateBootstrapToken(tokenHex string) (bool, error)

ValidateBootstrapToken checks if the provided token matches the stored bootstrap token AND has not yet been consumed by a successful first-admin registration.

Uses constant-time comparison on the token bytes themselves; the consumed_at check is performed via a separate, cheap DB query that runs only after the constant-time compare succeeds.

The token is single-use. Once handlers/bootstrap.go atomically sets consumed_at inside the admin-creation transaction, every subsequent validation returns (false, nil).

func ValidateDevAdminAuthentication

func ValidateDevAdminAuthentication(db *sql.DB, username, password, totpSecret string) error

ValidateDevAdminAuthentication performs complete end-to-end validation of dev admin authentication This function simulates the entire OPAQUE authentication flow internally to ensure the dev admin registration was successful and the system is working properly

func ValidateDevAdminTOTPWorkflow

func ValidateDevAdminTOTPWorkflow(db *sql.DB, user *models.User, totpSecret string) error

ValidateDevAdminTOTPWorkflow performs end-to-end TOTP validation for dev admin bootstrap. It verifies that the TOTP secret was stored correctly and can be decrypted, but does NOT generate or validate an actual TOTP code. This avoids "burning" a TOTP window during server startup, which would cause replay-detection failures if an admin login attempt happens within the same 30-second window (e.g., during e2e testing).

func ValidateOPAQUESetup

func ValidateOPAQUESetup(db *sql.DB) error

ValidateOPAQUESetup validates that the libopaque setup is properly configured

func ValidateTOTPCode

func ValidateTOTPCode(db *sql.DB, username, code string) error

ValidateTOTPCode validates a TOTP code with replay protection and shared MFA lockout.

func VerifyOpaqueKeyRotationPreconditions

func VerifyOpaqueKeyRotationPreconditions(db *sql.DB) error

VerifyOpaqueKeyRotationPreconditions ensures every active account is flagged for re-registration and no OPAQUE user records remain. Replacing server keys before these conditions hold routes logins through DeriveFakeUserRecord instead of the structured account_requires_reregistration response.

func WebAuthnAuthBegin

func WebAuthnAuthBegin(db *sql.DB, username string) (json.RawMessage, error)

WebAuthnAuthBegin starts a security-key authentication ceremony.

func WebAuthnAuthFinish

func WebAuthnAuthFinish(db *sql.DB, username string, credentialJSON []byte) error

WebAuthnAuthFinish verifies a security-key assertion and persists the updated sign counter.

func WebAuthnRegisterBegin

func WebAuthnRegisterBegin(db *sql.DB, username string) (options json.RawMessage, backupCodes []string, err error)

WebAuthnRegisterBegin starts security-key enrollment for a user.

func WebAuthnRegisterFinish

func WebAuthnRegisterFinish(db *sql.DB, username string, credentialJSON []byte) error

WebAuthnRegisterFinish completes security-key enrollment.

Types

type AdminMFAResetStats

type AdminMFAResetStats struct {
	CredentialsDeleted int64
	BackupCodesDeleted int64
	UsageLogsDeleted   int64
	BackupUsageDeleted int64
	AlreadyReset       bool
}

AdminMFAResetStats summarizes rows removed during an admin full MFA reset.

func AdminFullResetUserMFA

func AdminFullResetUserMFA(db *sql.DB, targetUsername string) (AdminMFAResetStats, error)

AdminFullResetUserMFA deletes all MFA credentials, backup codes, and usage logs for a user. It does not modify contact info or revoke sessions.

type ApplyEnvelopeMasterRotationOptions

type ApplyEnvelopeMasterRotationOptions struct {
	BaseDir          string
	SecretsEnvPath   string
	Mandate          string
	DB               *sql.DB
	SkipServiceCheck bool
	ServiceName      string
	BackupDirectory  string
}

ApplyEnvelopeMasterRotationOptions configures offline envelope master rotation.

type ApplyUserSecretMasterRotationOptions

type ApplyUserSecretMasterRotationOptions struct {
	BaseDir          string
	MasterKeyPath    string
	Mandate          string
	DB               *sql.DB
	SkipServiceCheck bool
	ServiceName      string
	BackupDirectory  string
	MasterKeyUID     int
	MasterKeyGID     int
}

ApplyUserSecretMasterRotationOptions configures offline user-secret master rotation.

type Claims

type Claims struct {
	Username    string `json:"username"`
	RequiresMFA bool   `json:"requires_mfa,omitempty"`
	jwt.RegisteredClaims
}

func GetClaimsFromContext

func GetClaimsFromContext(c echo.Context) (*Claims, bool)

GetClaimsFromContext returns parsed claims from context or nil

type EnvelopeRotationMandatePayload

type EnvelopeRotationMandatePayload struct {
	Purpose       string `json:"purpose"`
	AdminUsername string `json:"admin_username"`
	Nonce         string `json:"nonce"`
	IssuedAt      int64  `json:"issued_at"`
	ExpiresAt     int64  `json:"expires_at"`
}

EnvelopeRotationMandatePayload is the signed authorization for offline envelope master key rotation.

func VerifyEnvelopeRotationMandate

func VerifyEnvelopeRotationMandate(mandate string, publicKey ed25519.PublicKey) (*EnvelopeRotationMandatePayload, error)

VerifyEnvelopeRotationMandate validates the mandate signature and payload fields.

type JWTRotationResult

type JWTRotationResult struct {
	TempVersion int `json:"temp_version"`
	FullVersion int `json:"full_version"`
}

JWTRotationResult reports the active versions after a rotation.

func RotateJWTSigningKeys

func RotateJWTSigningKeys() (JWTRotationResult, error)

RotateJWTSigningKeys generates the next version for both the temp and full signing tiers, points each active-version metadata row at the new version, and reloads the in-memory key rings so the new keys take effect immediately. Previous versions remain in the verification set for the overlap window so that tokens already issued continue to validate until they expire.

type MFAData

type MFAData struct {
	SecretEncrypted []byte `json:"credential_data"`
	Enabled         bool   `json:"enabled"`
	SetupCompleted  bool   `json:"setup_completed"`
	CreatedAt       time.Time
	LastUsed        *time.Time
}

MFAData represents stored MFA credential state for a user.

type MFALockoutError

type MFALockoutError struct {
	Reason     string
	RetryAfter time.Duration
}

MFALockoutError is returned when an MFA attempt is rejected due to failure-rate lockout.

func (*MFALockoutError) Error

func (e *MFALockoutError) Error() string

type MFASetup

type MFASetup struct {
	Secret      string   `json:"secret"`
	QRCodeURL   string   `json:"qr_code_url"`
	QRCodeImage string   `json:"qr_code_image"`
	BackupCodes []string `json:"backup_codes"`
	ManualEntry string   `json:"manual_entry"`
}

MFASetup represents enrollment material for a TOTP second factor.

func GenerateMFASetup

func GenerateMFASetup(username string) (*MFASetup, error)

GenerateMFASetup creates new TOTP enrollment material for a user.

func GetPendingMFASetup

func GetPendingMFASetup(db *sql.DB, username string) (*MFASetup, error)

GetPendingMFASetup retrieves an existing pending (unverified) TOTP setup for a user.

func ResetMFA

func ResetMFA(db *sql.DB, username, backupCode string) (*MFASetup, error)

ResetMFA stages a new TOTP secret and fresh backup codes; verify must complete before MFA is active.

type OPAQUEServerKeys

type OPAQUEServerKeys struct {
	ServerPrivateKey []byte // 32-byte server private key (crypto_scalarmult_SCALARBYTES)
	OPRFSeed         []byte // 32-byte OPRF seed (crypto_core_ristretto255_SCALARBYTES)
	CreatedAt        time.Time
}

OPAQUEServerKeys represents the server's long-term key material for libopaque

type OPAQUEUserData

type OPAQUEUserData struct {
	Username         string
	SerializedRecord []byte // libopaque user record
	CreatedAt        time.Time
}

OPAQUEUserData represents the server-side storage for libopaque user data

type OpaqueKeyReplaceResult

type OpaqueKeyReplaceResult struct {
	PrivateKeyFingerprint string
	OPRFSeedFingerprint   string
	PreviousPrivateKeyFP  string
	PreviousOPRFSeedFP    string
}

OpaqueKeyReplaceResult reports the outcome of replacing only the server keys.

func ReplaceOpaqueServerKeys

func ReplaceOpaqueServerKeys() (OpaqueKeyReplaceResult, error)

ReplaceOpaqueServerKeys generates fresh OPAQUE server key material, overwriting the two system_keys rows, verifies the material changed, and reloads the in-memory keys without a restart.

func ReplaceOpaqueServerKeysGuarded

func ReplaceOpaqueServerKeysGuarded(db *sql.DB) (OpaqueKeyReplaceResult, error)

ReplaceOpaqueServerKeysGuarded replaces server keys only when every active account is already flagged and opaque_user_data is empty.

type OpaqueRotationResult

type OpaqueRotationResult struct {
	UsersFlagged          int64
	Usernames             []string
	PrivateKeyFingerprint string
	OPRFSeedFingerprint   string
	PreviousPrivateKeyFP  string
	PreviousOPRFSeedFP    string
}

OpaqueRotationResult reports the outcome of a deployment-wide OPAQUE key rotation (flag all accounts + replace server keys).

func RotateOpaqueServerKeysDeployment

func RotateOpaqueServerKeysDeployment(db *sql.DB) (OpaqueRotationResult, error)

RotateOpaqueServerKeysDeployment performs the recommended atomic deployment rotation: flag every active account, clear all OPAQUE user records, replace the server keys, and reload them in memory. Callers should force-logout the returned usernames so sessions pick up the new state immediately.

type UserSecretRotationMandatePayload

type UserSecretRotationMandatePayload struct {
	Purpose       string `json:"purpose"`
	AdminUsername string `json:"admin_username"`
	Nonce         string `json:"nonce"`
	IssuedAt      int64  `json:"issued_at"`
	ExpiresAt     int64  `json:"expires_at"`
}

UserSecretRotationMandatePayload is the signed authorization for offline user-secret master rotation.

func VerifyUserSecretRotationMandate

func VerifyUserSecretRotationMandate(mandate string, publicKey ed25519.PublicKey) (*UserSecretRotationMandatePayload, error)

VerifyUserSecretRotationMandate validates the mandate signature and payload fields.

Jump to

Keyboard shortcuts

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