Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AdminPass

A lightweight, self-hosted authentication gateway that puts password + TOTP protection in front of any internal HTTP service — Adminer, Grafana, Prometheus, or anything else you run behind Docker.


How it works

AdminPass listens on one port per service you define in adminpass.yaml. Every request hitting those ports is intercepted: if the user has a valid session cookie they are proxied through transparently; if not, they see a login form. A separate admin UI on port 8777 lets you manage user accounts and edit the service list.

Browser → :8080 (AdminPass) → adminer:8080
Browser → :8010 (AdminPass) → grafana:3000
Browser → :8777 (AdminPass) → admin panel

Sessions are in-memory, expire after 8 hours, and are reaped automatically every 15 minutes. All accounts require TOTP (RFC 6238) — there is no way to create an account without 2FA.


Configuration

The single config file is adminpass.yaml, placed in the working directory of the binary (or the Docker container root).

totp:
  issuer: "AdminPass"   # shown in the authenticator app
  period: 30                   # seconds per code (default 30)
  digits: 6                    # code length (default 6)

services:
  "8080": "adminer:8080"       # listen-port: upstream-host:upstream-port
  "8010": "grafana:3000"

The totp block is optional — all three fields have sensible defaults. The services map is the full list of proxied ports. Changes made through the admin UI are written back to this file immediately; new listeners only take effect after a process restart.

Environment variables

The database connection is configured entirely through environment variables. All have defaults suitable for a Docker Compose stack.

Variable Default Description
DB_HOST db MySQL hostname
DB_PORT 3306 MySQL port
DB_NAME wizzl Database name
DB_USER wizzl Database user
DB_PASS secret Database password

Running with Docker Compose

A minimal docker-compose.yml that wires AdminPass to a MySQL container:

services:
  adminpass:
    build: .
    container-name: adminpass
    ports:
      - "8080:8080"
      - "8010:8010"
      - "8777:8777"
    environment:
      DB_HOST: db
      DB_USER: wizzl
      DB_PASS: changeme
      DB_NAME: wizzl
    volumes:
      - ./adminpass.yaml:/adminpass.yaml
    depends_on:
      - db

  db:
    image: mysql:latest
    environment:
      MYSQL_DATABASE: wizzl
      MYSQL_USER: wizzl
      MYSQL_PASSWORD: changeme
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Expose only the ports you actually need. The admin panel on 8777 should never be exposed to the public internet.


First-run setup

  1. Start the stack. On first boot AdminPass runs the database migration automatically.
  2. Open http://your-host:8777 in a browser. You will be redirected to the First Setup screen.
  3. Enter an email address and a password of at least 12 characters, then click Create account & generate 2FA.
  4. Scan the QR code with an authenticator app (Google Authenticator, Authy, 1Password, etc.). This QR code is shown exactly once — save it or store the manual key before leaving the page.
  5. Click Continue to login and sign in with your email, password, and the 6-digit code from your authenticator app.

Admin panel

The admin panel is always available at :8777 and is independent of the proxied services.

Users tab

Displays every account with its email, creation date, and role. The founding admin (the first account ever created, identified by the lowest database ID) has two extra privileges:

  • Can create additional admin accounts via the Create user form.
  • Can delete any account other than their own.

Deleting a user immediately revokes all of their active sessions.

Services tab

Lists every entry currently in adminpass.yaml. From here you can:

  • Remove an existing service — takes effect immediately in the config file. The listener for that port will stop accepting new connections after a process restart.
  • Add a new service by providing a listen port, an upstream host, and an upstream port. The entry is written to adminpass.yaml at once; start a new listener by restarting the container.

Authentication flow

Each proxied port runs its own login page at /_adminpass/login. After a successful login the session token, a display hint (base64-encoded email), and the originating port are stored in three HttpOnly cookies scoped to /. Logging out at /_adminpass/logout revokes the token server-side and clears the cookies.

The admin panel at :8777 uses its own session that is independent of the per-service sessions — you may be logged into the admin UI and a proxied service at the same time.


Security notes

  • HTTPS: The cookies are currently set with Secure: false. If you terminate TLS upstream (e.g. with Caddy or Nginx), set Secure: true in auth.go and redeploy.
  • Admin port: Port 8777 should be firewalled or bound only to a private network interface. Exposing it publicly gives anyone a login page for your admin panel.
  • Database password: Change DB_PASS from the default secret before deploying anywhere.
  • Session storage: Sessions are held in memory. A process restart clears all active sessions and everyone will need to log in again.

Building from source

Requires Go 1.25.5 or later.

git clone git https://github.com/wizzldev/adminpass.git
cd adminpass
go build -o adminpass ./...
make config
./adminpass          # expects adminpass.yaml in the current directory

For a Docker image, use the provided Dockerfile:

docker build -t adminpass .

About

Zero-config reverse proxy that gates any internal HTTP service behind password + TOTP authentication, with a built-in admin UI for managing users and services.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages