Aegis is a self-hosted, plug-and-play authentication and authorization system inspired by Auth0, built for developers who want full control over their stack and data.
It’s simple to integrate, secure by default, and flexible enough to fit any application.
Aegis provides a centralized authentication service that your applications can plug into.
You can deploy it on your own infrastructure and use it as an internal authentication provider — your self-managed Auth0 alternative.
- User signup and login
- Email verification and password reset via Nodemailer
- JWT-based session management
- CORS-ready APIs for any frontend
- Configurable environment setup using
.env
Developers spend hours re-implementing the same authentication logic — often insecurely.
Aegis removes that burden.
- Ready-to-use signup, login, logout, and password reset endpoints
- Secure JWT token management and cookie handling
- Simple integration with any frontend or mobile app
- Self-hosted control over your data and users
- Built-in password reset and verification flow
Deploy it on your own infrastructure, and you have a complete authentication layer in minutes — no vendor lock-in, no external dependencies, no hidden data policies.
- Runtime: Node.js (Express)
- Database: PostgreSQL (demo hosted on Render)
- Authentication: JWT (via
jsonwebtoken) - Security:
bcryptjsfor password hashing - Mail Service:
nodemailer - CORS Support:
cors - Configuration:
dotenv
Aegis automatically initializes the required database schema on startup.
When the server starts, it checks for the existence of a users table and creates it if missing.
The table includes the following fields:
| Column | Type | Description |
|---|---|---|
id |
UUID | Primary key |
username |
VARCHAR(100) | User’s name |
email |
VARCHAR(100) | Unique user email |
password |
VARCHAR(255) | Hashed password |
password_reset_token |
VARCHAR(255) | Temporary token for password reset |
password_reset_token_expiry |
TIMESTAMP | Expiry time for the reset token |
created_at |
TIMESTAMP | Auto-generated timestamp |
updated_at |
TIMESTAMP | Auto-updated timestamp |
If you prefer manual setup, you can also run the SQL schema directly:
psql -U <db_user> -d <db_name> -f ./database/createTables.sqlgit clone https://github.com/ankurdas1998/aegis.git
cd aegisnpm installCopy the example environment file and update it with your configuration:
cp .env.example .envExample .env file:
# PORT=3000 -> change if needed (default: 3000)
FRONTEND_URL=http://localhost:5173
# DATABASE
DB_USER=<db_username>
DB_PASSWORD=<db_password>
DB_HOST=<db_host>
DB_PORT=<port>
DB_NAME=<db_name>
# JWT
JWT_SECRET=<your_jwt_secret_string>
# MAIL SERVICE
EMAIL_HOST=sandbox.smtp.mailtrap.io
EMAIL_PORT=<port>
EMAIL_USER=<smtp_username>
EMAIL_PASS=<smtp_password>
npm run devYour Aegis API should now be live at: http://localhost:3000
All API routes are versioned and namespaced under /api/v1.
| Method | Endpoint | Description |
|---|---|---|
| POST | /signup |
Register a new user with email and password |
| POST | /login |
Authenticate a user and return a JWT |
| POST | /forgot-password |
Send a password reset link to the user's email |
| POST | /verify-reset-token/:token |
Verify validity of the password reset token |
| POST | /reset-password/:token |
Reset password using a valid token |
| POST | /logout |
Invalidate the user’s active session |
curl --location 'http://localhost:3000/api/v1/auth/signup' --header 'Content-Type: application/json' --data-raw '{
"username": "testUser",
"email": "testuser@example.com",
"password": "topSecret@123"
}'Response
{
"status": "success",
"message": "User created successfully",
"user": {
"id": "597593c4-16ef-4e3e-b47c-2733b10bddb3",
"username": "testUser",
"email": "testuser@example.com"
}
}curl --location 'http://localhost:3000/api/v1/auth/login' --header 'Content-Type: application/json' --data-raw '{
"email": "testuser@example.com",
"password": "topSecret@123"
}'Response
{
"status": "success",
"message": "Login Successful",
"token": "eyJhbGciOiJIUzI1N..................",
"user": {
"id": "597593c4-16ef-4e3e-b47c-2733b10bddb3",
"username": "testUser",
"email": "testuser@example.com"
}
}curl --location 'http://localhost:3000/api/v1/dashboard' --header 'Authorization: Bearer <your_jwt_token>'Response
{
"status": "success",
"message": "Welcome testUser!",
"data": {
"id": "597593c4-16ef-4e3e-b47c-2733b10bddb3",
"username": "testUser"
}
}The /api/v1/dashboard route is an example of a protected endpoint.
You can create your own routes (e.g., /api/v1/profile, /api/v1/settings) and secure them using the same JWT middleware provided by Aegis.
This allows you to build custom business logic while keeping authentication centralized and secure.
import express from "express";
import { authenticateUser } from "../middleware/authMiddleware.js";
const router = express.Router();
router.get("/profile", authenticateUser, async (req, res) => {
const user = req.user; // user data injected by JWT middleware
res.status(200).json({
status: "success",
message: `Hello, ${user.username}!`,
data: { id: user.id, email: user.email },
});
});
export default router;Mount it in your app:
app.use("/api/v1/profile", profileRoute);- Self-hosted freedom — No vendor lock-in or data handoff.
- Simplicity first — Minimal setup, clear endpoints, lightweight dependencies.
- Security focus — Built around industry best practices for credential and token handling.
Built and maintained by Ankur Das
Licensed under the ISC License.