NAME

Concierge::Auth - Password authentication and token generation using Crypt::Passphrase

VERSION

v0.19.0

SYNOPSIS

use Concierge::Auth;

# Initialize with a password file
my $auth = Concierge::Auth->new({ file => '/path/to/auth.pwd' });

# Or without a file (generators and utilities only)
my $auth = Concierge::Auth->new({ no_file => 1 });

# Register a new user
my ($ok, $msg) = $auth->setPwd('alice', 'secret123');

# Authenticate
my ($ok, $msg) = $auth->checkPwd('alice', 'secret123');

# Check if a user exists
my ($ok, $msg) = $auth->checkID('alice');

# Change password
my ($ok, $msg) = $auth->resetPwd('alice', 'newsecret456');

# Delete a user
my ($ok, $msg) = $auth->deleteID('alice');

# Generate tokens and random values
my ($uuid, $msg)   = $auth->gen_uuid();           # v4 UUID
my ($id, $msg)     = $auth->gen_random_id();       # 40-char hex ID
my ($token, $msg)  = $auth->gen_random_token(32);
my ($string, $msg) = $auth->gen_random_string(16);
my ($phrase, $msg) = $auth->gen_word_phrase(4, 4, 7, '-');

DESCRIPTION

Concierge::Auth provides password authentication backed by Crypt::Passphrase with Argon2 encoding and Bcrypt validation for legacy password migration. Passwords are stored in a tab-separated file with file-locking for concurrent access.

The module also provides token and random value generation via its parent class Concierge::Auth::Generators, which uses Crypt::PRNG for cryptographically secure random output.

Concierge::Auth is the authentication component of the Concierge suite, alongside Concierge::Sessions (session management) and Concierge::Users (user data storage). It can also be used standalone.

Return Convention

After construction, methods never croak. All checking and mutation methods return a boolean/message pair that adapts to calling context:

# Scalar context -- boolean only
if ($auth->checkPwd($id, $password)) { ... }

# List context -- boolean + message
my ($ok, $msg) = $auth->checkPwd($id, $password);

Success returns are produced by the internal confirm() helper; failures by reject(). The general-purpose reply($bool, $msg) helper is used when the outcome is computed at runtime.

Password Security

  • Encoder: Argon2 (memory-hard, resistant to GPU/ASIC attacks)

  • Validator: Bcrypt (accepts legacy hashes, re-hashes on next setPwd/resetPwd)

  • Password length: 8-72 characters (Bcrypt upper limit)

  • User ID: 2-32 characters, alphanumeric plus ., _, @, -

CONSTRUCTOR

new

my $auth = Concierge::Auth->new(\%args);

Creates a new Auth object. The Crypt::Passphrase encoder (Argon2) is initialized immediately.

Arguments:

file -- path to the password file. Created if it does not exist. File permissions are set to 0600. Croaks if the file cannot be opened or created.
no_file -- if true, skip file setup. The object can still generate tokens and hash passwords, but cannot perform ID or password checks.

If neither file nor no_file is provided, the object is still created (with a warning), but file-dependent methods will fail.

METHODS

Authentication

checkID

my ($ok, $msg) = $auth->checkID($user_id);

Returns true if $user_id has a record in the password file.

checkPwd

my ($ok, $msg) = $auth->checkPwd($user_id, $password);

Returns true if $password matches the stored hash for $user_id.

setPwd

my ($ok, $msg) = $auth->setPwd($user_id, $password);

Creates a new password record for $user_id. Fails if the ID already exists (use resetPwd to change an existing password).

Returns the user ID as the message on success.

resetPwd

my ($ok, $msg) = $auth->resetPwd($user_id, $new_password);

Replaces the stored password hash for an existing $user_id. Fails if the ID is not found.

Returns the user ID as the message on success.

deleteID

my ($ok, $msg) = $auth->deleteID($user_id);

Removes the password record for $user_id. Fails if the ID is not found.

Validation

validateID

my ($ok, $msg) = $auth->validateID($user_id);

Checks whether $user_id meets the length and character constraints. Does not check the password file.

validatePwd

my ($ok, $msg) = $auth->validatePwd($password);

Checks whether $password meets the length constraints.

validateFile

my ($ok, $msg) = $auth->validateFile($file);

Returns true if $file (or the object's configured file) exists and is readable.

File Management

setFile

my ($ok, $msg) = $auth->setFile($path);

Sets (or changes) the password file path. Creates the file if it does not exist and sets permissions to 0600.

rmFile

my ($file, $msg) = $auth->rmFile();

Deletes the password file and clears the stored path. In list context, returns the deleted file path on success.

clearFile

my ($ok, $msg) = $auth->clearFile();

Removes and re-creates the password file, effectively deleting all records.

pfile

my ($file, $msg) = $auth->pfile();

Returns the path to the configured password file.

Utilities

encryptPwd

my $hash = $auth->encryptPwd($password);

Returns the Argon2 hash of $password. Validates password constraints first.

Token and Value Generation

These methods wrap the functions in Concierge::Auth::Generators and return results using the Auth reply convention: ($value, $message) in list context, $value in scalar context.

gen_uuid

my ($uuid, $msg) = $auth->gen_uuid();

Generates a version 4 (random) UUID using Crypt::PRNG::random_bytes. No external commands are used.

gen_random_id

my ($id, $msg) = $auth->gen_random_id();       # 20 bytes / 40 hex chars
my ($id, $msg) = $auth->gen_random_id(32);      # 32 bytes / 64 hex chars

Generates a hex-encoded random ID from cryptographic random bytes. Default is 20 bytes (40 hex characters, 160 bits). Suitable for session IDs, API keys, and other security tokens where UUID format is not required.

gen_random_token

my ($token, $msg) = $auth->gen_random_token($length);

Generates a cryptographically secure alphanumeric token. Default length is 13.

gen_crypt_token

my ($token, $msg) = $auth->gen_crypt_token();

Generates an 11-character token using crypt().

gen_random_string

my ($string, $msg) = $auth->gen_random_string($length, $charset);

Generates a random string of $length characters from $charset. Uses alphanumeric characters if $charset is omitted.

gen_word_phrase

my ($phrase, $msg) = $auth->gen_word_phrase($num_words, $min, $max, $sep);

Generates a multi-word passphrase from dictionary words (or random fallback strings). Defaults: 4 words, 4-7 characters each, no separator.

gen_token

Deprecated alias for gen_random_token.

SEE ALSO

Concierge::Auth::Generators -- functional interface to the generators

Concierge::Sessions, Concierge::Users -- companion Concierge components

Crypt::Passphrase, Crypt::PRNG

AUTHOR

Bruce Van Allen <bva@cruzio.com>

LICENSE

This module is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.