Self-hostable — your infrastructure, your rules

Deploy Your Own Aethelos Base

Host it for your team, your friends, or your company. Each developer gets their own account, isolated databases, and API keys. No vendor lock-in.

Prerequisites

# You need:
# 1. Node.js 18+ installed
# 2. A PostgreSQL 15+ cluster (can be local or remote)
# 3. Git

# Check your setup:
node --version    # v18+ required
psql --version    # PostgreSQL client

1. Clone the repository

# Clone Aethelos Base
git clone https://github.com/aethelos/base.git
cd base

# Install dependencies
npm install

2. Configure your environment

# Copy the example env file
cp .env.example .env.local

# Edit .env.local:

# ── Metadata database (stores projects, users, API keys, audit log) ──
DATABASE_URL=postgresql://aethelos:secret@localhost:5432/aethelos_base

# ── Cluster admin (used to provision new databases) ──
PG_CLUSTER_URL=postgresql://admin:secret@localhost:5432/postgres

# ── Secrets encryption (REQUIRED — encrypts 2FA seeds, signs tokens) ──
#    generate: openssl rand -base64 32
SECRETS_ENCRYPTION_KEY=
AUTH_SECRET=

# ── White-label branding (issuer in 2FA apps & generated SDKs) ──
NEXT_PUBLIC_BRAND=Your Product

# ── Paystack (optional — for paid upgrades) ──
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=your-paystack-public-key
PAYSTACK_SECRET_KEY=your-paystack-secret-key

# ── App URL ──
NEXT_PUBLIC_APP_URL=https://your-domain.com

3. Initialize the metadata database

# Create the metadata database
createdb aethelos_base

# Run the schema migration
psql -d aethelos_base -f init.sql

# This creates:
#   • baas_projects / baas_tables_schema / baas_api_metrics_logs
#   • developers / sessions / api_keys (hashed keys, roles, expiry)
#   • project_api_configs (CORS, rate limit, IP allowlist, white-label)
#   • custom_domains / security_events / email_verifications / api_rate_limits

# The app self-heals its schema on boot (idempotent ALTER/CREATE IF NOT
# EXISTS), so upgrading an older install needs no manual migration.

4. Start the server

# Development mode
npm run dev

# Production build
npm run build
npm start

# Aethelos Base is now running at:
# → http://localhost:3000

5. Deploy to production

# ── Option A: VPS (DigitalOcean, Hetzner, AWS EC2) ──
# 1. Provision a VPS with PostgreSQL 15
# 2. Clone the repo, set DATABASE_URL and PG_CLUSTER_URL
# 3. Run: npm run build && npm start
# 4. Use a reverse proxy (nginx/Caddy) with SSL

# ── Option B: Docker ──
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]

# docker build -t aethelos-base .
# docker run -p 3000:3000 \
#   -e DATABASE_URL=postgresql://... \
#   -e PG_CLUSTER_URL=postgresql://... \
#   aethelos-base

# ── Option C: Vercel / Railway ──
# Push to GitHub, connect to Vercel/Railway,
# set environment variables, deploy.
# Note: You still need a PostgreSQL cluster
# (Neon, Supabase PG, or self-hosted).

6. Invite your friends

# Once deployed, share the URL:
# → https://base.your-domain.com/signup

# Each developer:
#   1. Creates their own account
#   2. Gets isolated projects & databases
#   3. Generates their own API keys
#   4. Has full REST API access

# Everyone is fully isolated:
#   • Separate accounts
#   • Separate projects
#   • Separate PostgreSQL databases
#   • Separate API keys
#   • Separate telemetry

7. Harden & observe

# Aethelos Base ships with defense-in-depth enabled by default:
#
#   • CSP with a per-request NONCE (strict-dynamic) — no unsafe-inline
#     or unsafe-eval in production. Set by src/middleware.ts, which also
#     forces every page to render dynamically.
#   • HSTS, X-Frame-Options: DENY, nosniff, Referrer/Permissions-Policy.
#   • API keys stored only as SHA-256 digests (reveal-once, rotatable).
#   • scrypt password hashing, TOTP 2FA (AES-GCM at rest), login lockout.
#
# Ship the audit trail off-box so a DB rollback can't erase it:
SECURITY_EVENT_WEBHOOK_URL=https://siem.example.com/ingest
SECURITY_EVENT_WEBHOOK_TOKEN=<bearer>
# (each event is ALSO written to stdout as {"tag":"aethelos.audit",...}
#  for a log shipper: CloudWatch Agent / Grafana Alloy / Fluent Bit)

# Verify the whole path after setup (requires AUDIT_SELFTEST_TOKEN):
curl -X POST https://your-domain.com/api/v1/audit/selftest \
  -H "Authorization: Bearer $AUDIT_SELFTEST_TOKEN"
# → {"ok":true,"stdout":true,"webhook_configured":true,...}

Architecture


┌─────────────────────────────────────────────────────────┐
│                   Aethelos Base Server                   │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────────┐  │
│  │  Portal   │  │ REST API │  │  SDK Generator       │  │
│  │  (Next.js)│  │ /api/v1  │  │  /api/v1/sdk         │  │
│  └────┬─────┘  └────┬─────┘  └──────────┬───────────┘  │
│       │              │                    │              │
│  ┌────┴──────────────┴────────────────────┴───────────┐  │
│  │              DataStore Interface                    │  │
│  │   (auth, projects, tables, API keys, metrics)      │  │
│  └────────────────────┬───────────────────────────────┘  │
└───────────────────────┼──────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
  ┌─────┴─────┐  ┌─────┴─────┐  ┌─────┴─────┐
  │ Developer  │  │ Developer  │  │ Developer  │
  │ A's DB     │  │ B's DB     │  │ C's DB     │
  │ (isolated) │  │ (isolated) │  │ (isolated) │
  └───────────┘  └───────────┘  └───────────┘

Ready to self-host?

Clone the repo and deploy your own instance in under 10 minutes.