A self-hosted identity platform that provides authentication and authorization services for web, mobile, and API-based applications.
It aims to help developers implement authentication and authorization features in their applications without having to build these functionalities from scratch.
- Details. One-Time PIN (OTP) based on TOTP (Time-based One-Time Password), which is described in IETF RFC 6238.
- Details. Client authentication using JWT (JSON Web Token).
- Multitenancy
- Access groups & scoped permissions
- Two-Factor Authentication (2FA) using OTP via SMS or email.
- Rate limit/throttling.
-
Create a copy of the
.env.example
, omit the.example
:cp .env.example .env
-
Fill in the
.env
file. You may skip theDATABASE_URL
andREDIS_URL
variables.To generate a
APP_SECRET
, you may run:openssl rand -hex 20 | xxd -r -p | base32 | tr -d '='
The server requires a base32 string for RFC-6238 compliance.
-
Start the server:
docker-compose up
-
Clone the repo
-
Create a copy of the
.env.example
, omit the.example
:cp .env.example .env
-
Fill in the
.env
file. To generate a secret key, you may run:openssl rand -hex 20 | xxd -r -p | base32 | tr -d '='
-
Install Rust dependencies
cargo install cargo-watch sea-orm-cli
cargo-watch is optional, but it is recommended to use it for development. If you are using
cargo-watch
, you may runcargo watch -x run
instead. -
Run the server. This will also install other third-party dependencies:
cargo run
For an optimized build, run:
cargo build --release
Execute the binary:
./target/release/haltion
Make a POST request to /otps
with the following JSON body:
{
"phone_number": "+639123456789"
}
The response will be a JSON object with the following structure:
{
"sms_sent": true
}
If the sms_sent
field is false
, there will be a detail
field with the error message.
{
"sms_sent": false,
"detail": "The phone number is invalid."
}
Make a GET request to /otps/{otp}
with the following query parameters:
otp
: The OTP code.
The response will be a JSON object with the following structure:
{
"verified": true,
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"token_type": "Bearer"
}
If the verified
field is false
, there will be a detail
field with the error message.
{
"verified": false,
"detail": "Something went wrong."
}