Auth API
This page documents the public rix/auth API.
Use auth through the unified Rix facade:
#include <rix.hpp>Then access auth with:
rix.authThe auth API provides helpers for:
registration
login
password hashing
sessions
tokens
configuration
memory stores
error handlingPackage
The auth package is:
rix/authFor facade usage, install:
vix add rix/rix
vix installIn vix.app:
deps = [
"rix/rix",
]For independent package usage, install:
vix add rix/auth
vix installIn vix.app:
deps = [
"rix/auth",
]Header
Facade usage:
#include <rix.hpp>Independent usage:
#include <rix/auth.hpp>Most application examples should use the facade.
Facade member
The auth facade member is:
rix.authExample:
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
return registered.ok() ? 0 : 1;
}Main modules
rix.auth exposes several helper areas:
rix.auth.memory()
rix.auth.password
rix.auth.config
rix.auth.errorCommon usage:
auto auth = rix.auth.memory();
auto config = rix.auth.config.development();
auto hashed = rix.auth.password.hash("correct-password");
auto error_text = rix.auth.error.to_string(error);Create a memory auth service
Use:
auto auth = rix.auth.memory();This creates an auth service backed by in-memory user and session stores.
Memory auth is useful for:
examples
tests
local development
small demos
temporary applicationsMemory auth does not persist users or sessions after the process exits.
Create memory auth with config
auto config = rix.auth.config.development();
config.set_min_password_length(8);
config.set_session_ttl_seconds(60 * 60 * 24 * 7);
config.set_token_ttl_seconds(60 * 15);
auto auth = rix.auth.memory(config);Use configuration when you want to change password policy, token lifetime, session lifetime, or issuer.
Register a user
Use:
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});register_user returns an explicit result.
Check it before using the user:
if (registered.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(registered.error()),
registered.error().message());
return 1;
}Then use:
const auto &user = registered.value();Register request
A register request contains:
email
passwordExample:
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});The plain-text password is hashed before storage.
Do not log the plain-text password.
Login
Use:
auto login = auth.login({
"ada@example.com",
"correct-password"});login returns an explicit result.
Check it:
if (login.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(login.error()),
login.error().message());
return 1;
}Then use:
login.value().user
login.value().session
login.value().tokenLogin result
A successful login contains:
user
session
tokenExample:
rix.debug.print("user:", login.value().user.email());
rix.debug.print("session:", login.value().session.id());
rix.debug.print("issuer:", login.value().token.issuer());Session ids and token values are sensitive.
Do not print them in production logs.
Authenticate a session
Use:
auto session = auth.authenticate_session(
login.value().session.id());Check the result:
if (session.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(session.error()),
session.error().message());
return 1;
}Then:
rix.debug.print("session user id:", session.value().user_id());A session is valid when it exists, is not expired, and is not revoked.
Refresh a session
Use:
auto refreshed = auth.refresh_session(session_id);Check it:
if (refreshed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(refreshed.error()),
refreshed.error().message());
return 1;
}Then:
rix.debug.print("new expires at:", refreshed.value().expires_at());Refreshing a session extends its expiration according to the configured session lifetime.
Logout
Use:
auto status = auth.logout(session_id);Check it:
if (status.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(status.error()),
status.error().message());
return 1;
}Logout revokes the session.
A revoked session can remain stored, but it cannot be used for authentication.
Logout all sessions for a user
Use:
auto status = auth.logout_user(user_id);Example:
auto status = auth.logout_user(registered.value().id());
if (status.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(status.error()),
status.error().message());
return 1;
}This revokes all sessions belonging to the user.
Issue a token
Use:
auto token = auth.issue_token(user_id);Check it:
if (token.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(token.error()),
token.error().message());
return 1;
}Then read token metadata:
rix.debug.print("user id:", token.value().user_id());
rix.debug.print("issuer:", token.value().issuer());
rix.debug.print("issued at:", token.value().issued_at());
rix.debug.print("expires at:", token.value().expires_at());Do not log raw token values in production.
Password API
Password helpers are available through:
rix.auth.passwordCommon helpers:
rix.auth.password.hash(...)
rix.auth.password.verify(...)
rix.auth.password.accepts(...)
rix.auth.password.hasher()Hash a password
Use:
auto hashed = rix.auth.password.hash("correct-password");Check it:
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}Then store:
hashed.value()Do not store plain-text passwords.
Verify a password
Use:
const bool ok = rix.auth.password.verify(
"correct-password",
hashed.value());Wrong passwords return false:
const bool wrong = rix.auth.password.verify(
"wrong-password",
hashed.value());Example:
if (ok && !wrong)
{
rix.debug.print("password verification works");
}Check password policy
Use:
const bool accepted = rix.auth.password.accepts("correct-password");Example:
if (!rix.auth.password.accepts("short"))
{
rix.debug.eprint("password rejected by policy");
}hash also checks the password policy.
Create a password hasher
Use:
auto hasher = rix.auth.password.hasher();Then:
auto hashed = hasher.hash("correct-password");
const bool ok = hasher.verify(
"correct-password",
hashed.value());With configuration:
auto config = rix.auth.config.production();
auto hasher = rix.auth.password.hasher(config);For most application code, the facade helpers are enough.
Configuration API
Configuration helpers are available through:
rix.auth.configCommon helpers:
rix.auth.config.development()
rix.auth.config.production()Development configuration
Use:
auto config = rix.auth.config.development();Development configuration is useful for examples and local development.
It allows simple register and login flows.
Example:
auto auth = rix.auth.memory(
rix.auth.config.development());Production configuration
Use:
auto config = rix.auth.config.production();Production configuration is stricter.
It can require email verification before login.
Example:
auto auth = rix.auth.memory(
rix.auth.config.production());Use production configuration when building a real application flow.
Configuration setters
Common configuration setters include:
config.set_min_password_length(...)
config.set_session_ttl_seconds(...)
config.set_token_ttl_seconds(...)
config.set_issuer(...)
config.set_password_hash_iterations(...)
config.set_password_salt_size(...)
config.set_password_hash_size(...)Example:
auto config = rix.auth.config.development();
config.set_min_password_length(12);
config.set_session_ttl_seconds(60 * 60 * 24 * 7);
config.set_token_ttl_seconds(60 * 15);
config.set_issuer("my-app");
auto auth = rix.auth.memory(config);Error API
Error helpers are available through:
rix.auth.errorCommon helpers:
rix.auth.error.to_string(error)
rix.auth.error.is(error, code)Example:
if (registered.failed())
{
const auto &error = registered.error();
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(error),
error.message());
}Auth error codes
Auth error codes include:
rixlib::auth::AuthErrorCode::InvalidInput
rixlib::auth::AuthErrorCode::InvalidEmail
rixlib::auth::AuthErrorCode::InvalidPassword
rixlib::auth::AuthErrorCode::UserNotFound
rixlib::auth::AuthErrorCode::UserAlreadyExists
rixlib::auth::AuthErrorCode::InvalidCredentials
rixlib::auth::AuthErrorCode::InvalidSession
rixlib::auth::AuthErrorCode::SessionExpired
rixlib::auth::AuthErrorCode::InvalidToken
rixlib::auth::AuthErrorCode::TokenExpired
rixlib::auth::AuthErrorCode::InvalidState
rixlib::auth::AuthErrorCode::StoreError
rixlib::auth::AuthErrorCode::UnknownUse error codes for programmatic decisions.
Use messages for diagnostics.
Check a specific error
if (rix.auth.error.is(
login.error(),
rixlib::auth::AuthErrorCode::InvalidCredentials))
{
rix.debug.eprint("login failed:", "invalid credentials");
}This lets your app react differently depending on the failure.
Result pattern
Auth APIs use explicit results.
For operations that return a value:
auto result = auth.login({
"ada@example.com",
"correct-password"});
if (result.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(result.error()),
result.error().message());
return 1;
}
const auto &login = result.value();Never call value() before checking success.
Status pattern
Some operations return a status.
Example:
auto status = auth.logout(session_id);
if (status.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(status.error()),
status.error().message());
return 1;
}Use:
status.ok()
status.failed()
status.error()User API
A user value exposes user information.
Common methods include:
user.id()
user.email()
user.active()
user.email_verified()Example:
const auto &user = registered.value();
rix.debug.print("id:", user.id());
rix.debug.print("email:", user.email());Do not print password hashes in application output.
Session API
A session value exposes session information.
Common methods include:
session.id()
session.user_id()
session.created_at()
session.expires_at()
session.revoked()
session.expired(...)
session.usable(...)Example:
const auto &session = login.value().session;
rix.debug.print("user id:", session.user_id());
rix.debug.print("expires at:", session.expires_at());Session ids are sensitive.
Avoid logging raw session ids in production.
Token API
A token value exposes token information.
Common methods include:
token.value()
token.user_id()
token.issuer()
token.issued_at()
token.expires_at()
token.revoked()
token.revoke()
token.expired(...)
token.usable(...)
token.belongs_to(...)
token.issued_by(...)Example:
const auto &token = login.value().token;
rix.debug.print("issuer:", token.issuer());
rix.debug.print("expires at:", token.expires_at());The raw token value is sensitive.
Avoid logging:
token.value()in production.
Complete register and login example
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
if (registered.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(registered.error()),
registered.error().message());
return 1;
}
auto login = auth.login({
"ada@example.com",
"correct-password"});
if (login.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(login.error()),
login.error().message());
return 1;
}
auto session = auth.authenticate_session(
login.value().session.id());
if (session.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(session.error()),
session.error().message());
return 1;
}
rix.debug.print("authenticated user id:", session.value().user_id());
return 0;
}Run:
vix run auth.cppComplete password hashing example
#include <rix.hpp>
int main()
{
auto hashed = rix.auth.password.hash("correct-password");
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}
const bool valid = rix.auth.password.verify(
"correct-password",
hashed.value());
const bool invalid = rix.auth.password.verify(
"wrong-password",
hashed.value());
if (!valid || invalid)
{
return 1;
}
rix.debug.print("password verification successful");
return 0;
}Complete session example
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"grace@example.com",
"correct-password"});
if (registered.failed())
{
return 1;
}
auto login = auth.login({
"grace@example.com",
"correct-password"});
if (login.failed())
{
return 1;
}
const auto session_id = login.value().session.id();
auto refreshed = auth.refresh_session(session_id);
if (refreshed.failed())
{
return 1;
}
auto logout = auth.logout(session_id);
if (logout.failed())
{
return 1;
}
auto after_logout = auth.authenticate_session(session_id);
return after_logout.failed() ? 0 : 1;
}Complete token example
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"linus@example.com",
"correct-password"});
if (registered.failed())
{
return 1;
}
auto token = auth.issue_token(
registered.value().id());
if (token.failed())
{
return 1;
}
rix.debug.print("issuer:", token.value().issuer());
rix.debug.print("expires at:", token.value().expires_at());
return 0;
}Use in a Vix route
#include <vix.hpp>
#include <rix.hpp>
int main()
{
vix::App app;
auto auth = rix.auth.memory();
app.post("/register", [&](vix::Request &, vix::Response &res) {
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
if (registered.failed())
{
res.status(400).json({
"ok", false,
"error", rix.auth.error.to_string(registered.error()),
"message", registered.error().message()});
return;
}
res.json({
"ok", true,
"email", registered.value().email()});
});
app.run();
return 0;
}For durable applications, use database-backed stores instead of memory stores.
Use in a Vix project
Create a Vix app:
vix new rix-auth-api --app
cd rix-auth-apiAdd Rix:
vix add rix/rix
vix installMake sure vix.app contains:
deps = [
"rix/rix",
]Use in src/main.cpp:
#include <rix.hpp>Build and run:
vix build
vix runSingle-file usage
Create a file:
mkdir -p ~/rix-auth-api
cd ~/rix-auth-api
touch auth.cppAdd:
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
return 0;
}Run:
vix run auth.cppIf Rix is not available globally:
vix install -g rix/rix
vix run auth.cppIndependent usage
Install only auth:
vix add rix/auth
vix installIn vix.app:
deps = [
"rix/auth",
]Then include:
#include <rix/auth.hpp>Use independent package APIs when you intentionally do not want the unified facade.
For most documentation and application examples, prefer:
#include <rix.hpp>and:
rix.authSecurity notes
Do not log:
plain-text passwords
password hashes
raw token values
session idsUse HTTPS in production.
Use durable stores for real user accounts.
Use stricter configuration for production.
Keep token lifetimes short.
Keep session lifetimes intentional.
Require email verification when your application needs it.
Common mistakes
Forgetting to install Rix
If your code uses:
#include <rix.hpp>install:
vix add rix/rix
vix installPutting Rix in packages
Wrong:
packages = [
"rix/rix",
]Correct:
deps = [
"rix/rix",
]deps is for Vix Registry packages.
packages is for CMake package discovery.
Calling value() before checking success
Wrong:
auto login = auth.login({
"ada@example.com",
"correct-password"});
rix.debug.print(login.value().user.email());Correct:
auto login = auth.login({
"ada@example.com",
"correct-password"});
if (login.failed())
{
return 1;
}
rix.debug.print(login.value().user.email());Printing sensitive values
Avoid printing:
passwords
password hashes
tokens
session idsExpecting memory auth to persist
Memory auth is not durable.
When the process exits, users and sessions are gone.
Use database-backed stores for real applications.
Using production config without email verification flow
Production config can require email verification before login.
For simple examples, use:
auto auth = rix.auth.memory();or:
auto auth = rix.auth.memory(
rix.auth.config.development());Treating tokens and sessions as the same thing
A session is server-side authentication state.
A token is a short-lived value issued for a user.
They have separate lifetimes:
config.set_session_ttl_seconds(...);
config.set_token_ttl_seconds(...);What you should remember
Create auth:
auto auth = rix.auth.memory();Register:
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});Login:
auto login = auth.login({
"ada@example.com",
"correct-password"});Authenticate session:
auto session = auth.authenticate_session(
login.value().session.id());Hash password:
auto hashed = rix.auth.password.hash("correct-password");Verify password:
const bool ok = rix.auth.password.verify(
"correct-password",
hashed.value());Issue token:
auto token = auth.issue_token(user_id);Always check failed() before using value().
For project usage:
vix add rix/rix
vix installand keep:
deps = [
"rix/rix",
]Next step
Continue with the CSV API.
Next: CSV API