Documentation
¶
Index ¶
- Constants
- Variables
- func ActiveJWTKeyIDs() (tempKeyID, fullKeyID string, err error)
- func ActiveJWTKeyVersions() (tempVersion, fullVersion int, err error)
- func ApplyEnvelopeMasterRotation(opts ApplyEnvelopeMasterRotationOptions) (crypto.EnvelopeRotationStats, error)
- func ApplyUserSecretMasterRotation(opts ApplyUserSecretMasterRotationOptions) (crypto.UserSecretRotationStats, error)
- func CanDecryptMFASecret(db *sql.DB, username string) (present bool, decryptable bool, enabled bool, setupCompleted bool, err error)
- func CheckAndGenerateBootstrapToken(db *sql.DB) error
- func CleanupExpiredSessions(db *sql.DB) error
- func CleanupExpiredTokens(db *sql.DB) error
- func CleanupMFALogs(db *sql.DB) error
- func ClearWebAuthnSessionsForUser(username string)
- func ClientCreateCredentialRequest(password []byte) ([]byte, []byte, error)
- func ClientCreateRegistrationRequest(password []byte) ([]byte, []byte, error)
- func ClientFinalizeRegistration(usrCtx []byte, serverResponse []byte, username string, serverID string) ([]byte, []byte, error)
- func ClientRecoverCredentials(sec []byte, serverResponse []byte, username string, serverID string) ([]byte, []byte, []byte, error)
- func CompleteMFASetup(db *sql.DB, username, testCode string) error
- func ConsumeEnvelopeRotationMandate(db *sql.DB, nonce string) error
- func ConsumeUserSecretRotationMandate(db *sql.DB, nonce string) error
- func CreateAuthSession(db *sql.DB, username string, flowType string, serverPublicKey []byte) (string, error)
- func CreateCredentialResponse(credentialRequest []byte, userRecord []byte, username string) ([]byte, []byte, error)
- func CreateDevAdminWithOPAQUE(db *sql.DB, username, password string) (*models.User, error)
- func CreateRegistrationResponse(requestData []byte) ([]byte, []byte, error)
- func DeleteAllRefreshTokensForUser(db *sql.DB, username string) error
- func DeleteAuthSession(db *sql.DB, sessionID string) error
- func DeriveFakeUserRecord(username string) ([]byte, error)
- func GenerateFullAccessToken(username string) (string, time.Time, error)
- func GenerateRefreshToken() (string, error)
- func GenerateReregistrationToken(username string) (string, time.Time, error)
- func GenerateTemporaryMFAToken(username string) (string, time.Time, error)
- func GenerateTemporaryResetToken(username string) (string, time.Time, error)
- func GetJWTFullPrivateKey() ed25519.PrivateKey
- func GetJWTFullPublicKey() ed25519.PublicKey
- func GetJWTFullVerificationKeys() []ed25519.PublicKey
- func GetJWTTempPrivateKey() ed25519.PrivateKey
- func GetJWTTempPublicKey() ed25519.PublicKey
- func GetJWTTempVerificationKeys() []ed25519.PublicKey
- func GetOPAQUEServer() (bool, error)
- func GetPendingMFAMethodType(db *sql.DB, username string) (string, error)
- func GetServerPrivateKey() ([]byte, error)
- func GetUserMFAMethodType(db *sql.DB, username string) (string, error)
- func GetUsernameFromToken(c echo.Context) string
- func GetWebAuthn() (*webauthn.WebAuthn, error)
- func HashToken(token string) (string, error)
- func InvalidateUserRevocationCache(username string)
- func IsOPAQUEAvailable() bool
- func IsRevoked(db *sql.DB, tokenID string) (bool, error)
- func IsUserMFAEnabled(db *sql.DB, username string) (bool, error)
- func IssueEnvelopeRotationMandate(db *sql.DB, adminUsername string) (mandate string, expiresAt time.Time, err error)
- func IssueUserSecretRotationMandate(db *sql.DB, adminUsername string) (mandate string, expiresAt time.Time, err error)
- func JWTMiddleware() echo.MiddlewareFunc
- func LoadJWTFullKeys() error
- func LoadJWTKeys() error
- func LoadJWTTempKeys() error
- func LoadWebAuthnSession(username string, kind webAuthnSessionKind) (webauthn.SessionData, error)
- func MFAJWTMiddleware() echo.MiddlewareFunc
- func MFAResetJWTMiddleware() echo.MiddlewareFunc
- func MarshalWebAuthnOptions(v interface{}) (json.RawMessage, error)
- func OpaqueServerID() string
- func ParseEdDSAClaimsAnyFullKey(parser *jwt.Parser, tokenString string, claims jwt.Claims) (*jwt.Token, error)
- func ReloadJWTKeys() error
- func ReloadOpaqueServerKeys() error
- func RequireFullJWT(next echo.HandlerFunc) echo.HandlerFunc
- func RequiresMFAFromToken(c echo.Context) bool
- func ReregistrationJWTMiddleware() echo.MiddlewareFunc
- func ResetJWTMiddleware() echo.MiddlewareFunc
- func ResetKeysForTest()
- func ResetOpaqueServerKeysForTest()
- func RetireJWTKeyVersion(version int) error
- func RevokeAllUserJWTTokens(db *sql.DB, username, reason string) error
- func RevokeToken(db *sql.DB, tokenString, reason string) error
- func SaveWebAuthnSession(username string, kind webAuthnSessionKind, data *webauthn.SessionData) error
- func SetupDevAdminTOTP(db *sql.DB, user *models.User, totpSecret string) error
- func SetupServerKeys(db *sql.DB) error
- func StoreMFASetup(db *sql.DB, username string, setup *MFASetup) error
- func StoreUserRecord(rsec []byte, rrec []byte) ([]byte, error)
- func StoreWebAuthnPendingSetup(db *sql.DB, username string, backupCodes []string) error
- func TokenRevocationMiddleware(db *sql.DB) echo.MiddlewareFunc
- func UserAuth(authUServer []byte, authUClient []byte) error
- func ValidateAuthSession(db *sql.DB, sessionID string, expectedFlowType string) (username string, serverPk []byte, err error)
- func ValidateBackupCode(db *sql.DB, username, code string) error
- func ValidateBootstrapToken(tokenHex string) (bool, error)
- func ValidateDevAdminAuthentication(db *sql.DB, username, password, totpSecret string) error
- func ValidateDevAdminTOTPWorkflow(db *sql.DB, user *models.User, totpSecret string) error
- func ValidateOPAQUESetup(db *sql.DB) error
- func ValidateTOTPCode(db *sql.DB, username, code string) error
- func VerifyOpaqueKeyRotationPreconditions(db *sql.DB) error
- func WebAuthnAuthBegin(db *sql.DB, username string) (json.RawMessage, error)
- func WebAuthnAuthFinish(db *sql.DB, username string, credentialJSON []byte) error
- func WebAuthnRegisterBegin(db *sql.DB, username string) (options json.RawMessage, backupCodes []string, err error)
- func WebAuthnRegisterFinish(db *sql.DB, username string, credentialJSON []byte) error
- type AdminMFAResetStats
- type ApplyEnvelopeMasterRotationOptions
- type ApplyUserSecretMasterRotationOptions
- type Claims
- type EnvelopeRotationMandatePayload
- type JWTRotationResult
- type MFAData
- type MFALockoutError
- type MFASetup
- type OPAQUEServerKeys
- type OPAQUEUserData
- type OpaqueKeyReplaceResult
- type OpaqueRotationResult
- type UserSecretRotationMandatePayload
Constants ¶
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
const ( EnvelopeRotationMandatePurpose = "envelope-master-rotation" EnvelopeRotationMandateTTL = 10 * time.Minute )
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.
const ( MFAMethodTOTP = "totp" MFAMethodWebAuthn = "webauthn" )
const ( TOTPIssuer = "Arkfile" TOTPDigits = 6 TOTPPeriod = 30 TOTPSkew = 1 // Allow ±1 window (accepts current, previous, and next 30s windows) BackupCodeLength = 10 BackupCodeCount = 10 )
const ( OpaqueServerPrivateKeyID = "opaque_server_private_key" OpaqueOPRFSeedKeyID = "opaque_oprf_seed" OpaqueKeyType = "opaque" )
Opaque server key ids in system_keys (shared with rotation tooling).
const ( UserSecretRotationMandatePurpose = "user-secret-master-rotation" UserSecretRotationMandateTTL = 10 * time.Minute )
const BackupCodeCharset = "ACDEFGHJKLMNPQRTUVWXY34679"
Human-friendly backup code character set (excludes B/8, O/0, I/1, S/5, Z/2)
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 ¶
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.
var Echo *echo.Group
Echo is the Echo group with authentication middleware applied
Functions ¶
func ActiveJWTKeyIDs ¶
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 ¶
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 ¶
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 ¶
CleanupExpiredSessions removes all expired sessions
func CleanupExpiredTokens ¶
CleanupExpiredTokens removes expired per-JTI entries from revoked_tokens.
func CleanupMFALogs ¶
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 ¶
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 ¶
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 ¶
CompleteMFASetup validates a test code and enables MFA for the user.
func ConsumeEnvelopeRotationMandate ¶
ConsumeEnvelopeRotationMandate marks a mandate nonce as used.
func ConsumeUserSecretRotationMandate ¶
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 ¶
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 ¶
CreateRegistrationResponse handles server-side step of registration Takes client's registration request (M) and returns server response (rpub) and secret (rsec)
func DeleteAuthSession ¶
DeleteAuthSession removes a session after use
func DeriveFakeUserRecord ¶
DeriveFakeUserRecord deterministically generates a fake 256-byte OPAQUE user record for a non-existent username
func GenerateFullAccessToken ¶
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 ¶
GenerateRefreshToken creates a cryptographically secure random string to be used as a refresh token. It aims for approximately 256 bits of entropy.
func GenerateReregistrationToken ¶
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 ¶
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 ¶
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 ¶
GetJWTFullPublicKey returns the active Ed25519 public key for full tokens.
func GetJWTFullVerificationKeys ¶
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 ¶
GetJWTTempPublicKey returns the active Ed25519 public key for temp tokens.
func GetJWTTempVerificationKeys ¶
GetJWTTempVerificationKeys returns every temp-tier public key currently accepted for verification, active version first.
func GetOPAQUEServer ¶
GetOPAQUEServer returns a simple status check for libopaque server readiness
func GetPendingMFAMethodType ¶
GetPendingMFAMethodType returns method_type for an in-progress enrollment row.
func GetServerPrivateKey ¶
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 ¶
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 GetWebAuthn ¶
GetWebAuthn returns the shared WebAuthn relying-party instance.
func HashToken ¶
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 IsUserMFAEnabled ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
StoreMFASetup stores enrollment data with user-secret master encryption and hashed backup codes.
func StoreUserRecord ¶
StoreUserRecord finalizes registration by storing the user record Takes the server secret and client's finalized registration record, returns complete user record
func StoreWebAuthnPendingSetup ¶
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 ¶
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 ¶
ValidateBackupCode validates and consumes a hashed backup code (method-agnostic).
func ValidateBootstrapToken ¶
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 ¶
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 ¶
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 ¶
ValidateOPAQUESetup validates that the libopaque setup is properly configured
func ValidateTOTPCode ¶
ValidateTOTPCode validates a TOTP code with replay protection and shared MFA lockout.
func VerifyOpaqueKeyRotationPreconditions ¶
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 ¶
WebAuthnAuthBegin starts a security-key authentication ceremony.
func WebAuthnAuthFinish ¶
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.
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
}
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 ¶
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 ¶
GenerateMFASetup creates new TOTP enrollment material for a user.
func GetPendingMFASetup ¶
GetPendingMFASetup retrieves an existing pending (unverified) TOTP setup for a user.
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.
Source Files
¶
- bootstrap.go
- constants.go
- dev_admin.go
- envelope_rotation_apply.go
- envelope_rotation_mandate.go
- jwt.go
- jwt_rotation.go
- keys.go
- mfa_admin_reset.go
- mfa_backup_codes.go
- mfa_internal.go
- mfa_lockout.go
- mfa_maintenance.go
- mfa_methods.go
- mfa_setup.go
- mfa_totp.go
- mfa_types.go
- mfa_webauthn.go
- mfa_webauthn_config.go
- mfa_webauthn_session.go
- mfa_webauthn_store.go
- mfa_webauthn_user.go
- opaque.go
- opaque_client.go
- opaque_multi_step.go
- opaque_rotation.go
- token_revocation.go
- user_secret_rotation_apply.go
- user_secret_rotation_mandate.go