VaulTLS

VaulTLS

Docker app from SkyThes' Repository

Overview

Selfhostable web app to manage mTLS certificates: create, distribute and track expirations, with optional OIDC login and ACME CA support (Traefik, acme.sh). Recommended to run behind a reverse proxy for TLS termination.

VaulTLS Logo

VaulTLS is a modern solution for managing mTLS (mutual TLS) certificates with ease. It provides a centralized platform for generating, managing, and distributing TLS certificates for your home lab.

The main reason why I developed VaulTLS was that I didn't like messing with shell scripts and OpenSSL. I also did not have an overview about the expiration of individual certificates.

WebUI Overview

Features

  • 🔒 Comprehensive TLS X.509 certificate management
  • 💻 SSH certificate management
  • 📱 Modern web interface for certificate management
  • 🔐 OpenID Connect authentication support
  • 📨 Email notifications for certificate expiration
  • 🚀 RESTful API for automation
  • 🤖 ACME CA support (Traefik, acme.sh, and other ACME clients)
  • 🛠 Docker/Podman container support
  • ⚡ Built with Rust (backend) and Vue.js (frontend) for performance and reliability

Screenshots

WebUI CAs WebUI Users

Installation

Installation is managed through a Container. The app should be behind a reverse proxy for TLS handling. VAULTLS_API_SECRET is required and should be a 256-bit base64 encoded string (openssl rand -base64 32). If you want to access VaulTLS using non-HTTPS you need to add the following environmental variable: VAULTLS_INSECURE=true.

podman run -d \
  --name vaultls \
  -p 5173:80 \
  -v vaultls-data:/app/data \
  -e VAULTLS_API_SECRET="[VAULTLS_API_SECRET]" \
  -e VAULTLS_URL="https://vaultls.example.com/" \
  ghcr.io/7ritn/vaultls:latest

Encrypting the Database

By specifying the VAULTLS_DB_SECRET environmental variable, the database is encrypted. Data is retained. It is not possible to go back.

Specifying log level

The default log level is moderate. If a different one is desired, please specify it using the VAULTLS_LOG_LEVEL environmental variable. For bug reports, a trace or debug log report is desirable. Be aware logs can contain secrets. Please censor them before posting. Available options are: error, warn, info, debug and trace.

Setting up OIDC

To set up OIDC you need to create a new client in your authentication provider. For Authelia a configuration could look like this

- client_id: "[client_id]"
  client_name: "vautls"
  client_secret: "[client_secret_hash]"
  public: false
  authorization_policy: "one_factor"
  pkce_challenge_method: "S256"
  redirect_uris:
    - "https://vaultls.example.com/api/auth/oidc/callback"
  scopes:
    - "openid"
    - "profile"
    - "email"
  userinfo_signed_response_alg: "none"

For VaulTLS the required variables can be configured via environmental variables or web UI.

Environment Variable Value
VAULTLS_OIDC_AUTH_URL https://auth.example.com
VAULTLS_OIDC_CALLBACK_URL https://vaultls.example.com/api/auth/oidc/callback
VAULTLS_OIDC_ID [client_id]
VAULTLS_OIDC_SECRET [client_secret]

Some OIDC providers such as Zitadel supply multiple elements in the aud claim. To specify additional trusted audiences, specify them in a comma-separated list in the VAULTLS_OIDC_ADDITIONAL_AUDIENCES env variable or in the settings file. Configuration via web UI is not possible.

Container Secrets

Certain environment variables can be container secrets instead of regular variables. VaulTLS will try to read secrets from /run/secrets/<ENV_NAME>, if you want to specify a different path, you can do so in the environmental variable. The following variables support secrets:

  • VAULTLS_API_SECRET
  • VAULTLS_DB_SECRET
  • VAULTLS_OIDC_SECRET

Usage

During the first setup a TLS Certificate Authority is automatically created. If OIDC is configured, no password needs to be set. Users can either log in via password or OIDC. If a user first logs in via OIDC, their e-mail is matched with all VaulTLS users and linked. If no user is found, a new one is created.

Users can only see certificates created for them. Only admins can create new certificates. User certificates can be downloaded through the web interface.

The current CA certificate to be integrated with your reverse proxy is available as a file at /app/data/ca/ca.cert and as download via the API endpoint /api/certificates/ca/download.

Further API documentation is available at the endpoint /api

TLS Certificate Passwords

Certificates downloaded come in the PKCS#12 file format. They are a bundle consisting of the public certificate and private key. By default, PKCS#12 passwords are optional and certificates will be generated with no password. On the settings page, the PKCS#12 password requirements can be set with the following options:

PKCS12 Password Rule Result
Optional Passwords are optional and can be blank
Required Passwords are required, and can be user supplied
System Generated Random passwords will be generated

Passwords are stored in the database and retrieved from the web interface only when the user clicks on view password.

TLS Server Certificates

VaulTLS also has support for server certificates. The user flow remains quite similar with the difference that SAN DNS entries can be specified. Download is also using a possibly password-protected PKCS#12 file. Since most reverse proxies require the certificate and private key to be supplied separately, the PKCS#12 file may need to be split. This can be done, for example, with openssl:

openssl pkcs12 -in INFILE.p12 -out OUTFILE.crt -nokeys
openssl pkcs12 -in INFILE.p12 -out OUTFILE.key -nodes -nocerts

Certificate Revocation Lists (CRL)

TLS certificates cannot be simply deleted since their validity period is cryptographically encoded in the certificate. VaulTLS provides the CRL mechanism to revoke certificates. This file is used by the validation side (such as the server for client certificates) to check if the certificate has been revoked. CRLs are stored as files under /app/data/crl/. They can be downloaded in the CA tab of the frontend and can be retrieved from the API under /api/certificates/ca/<id>/crl. They do not require authentication to be accessed. Furthermore, VaulTLS hosts the CRL file directory under port 2277. This port can be exposed publicly. In combination with the CRL Distribution Point extension, you can specify the URL from where the CRL files are available for automatic validation. Specify URL using the VAULTLS_CRL_DP_URL env variable.

SSH Certificates

VaulTLS also supports SSH certificates. To use these you must manually create a new SSH CA in the CA tab. Since SSH does not provide a bundled file format to store the private key and certificate, the file is provided as a ZIP archive.

Caddy

To use caddy as a reverse proxy for the VaulTLS app, a configuration like the following is required.

reverse_proxy 127.0.0.1:5173

To integrate the CA cert for client validation, you can either use a file or http based approach. Extend your TLS instruction for that with the client_auth section. Documentation here: https://caddyserver.com/docs/caddyfile/directives/tls#client_auth.

File based:

tls {
  client_auth {
    mode <usually verify_if_given OR require_and_verify>
    trust_pool file {
      pem_file <Path to VaulTLS Directory>/ca.cert
    }
  }
}

HTTP based:

tls {
  client_auth {
    mode <usually verify_if_given OR require_and_verify>
    trust_pool http {
      endpoints <Address of VaulTLS Instance such as 127.0.0.1:5173>/api/certificates/ca/download
    }
  }
}

If you choose verify_if_given, you can still block clients for apps that you want to require client authentication:

@blocked {
  vars {tls_client_subject} ""
}
abort @blocked

ACME

VaulTLS can act as an ACME Certificate Authority, allowing clients like Traefik and acme.sh to automatically obtain certificates signed by your VaulTLS CA.

Enable it with VAULTLS_ACME_ENABLED=true and create an account in the ACME tab of the admin UI to get EAB credentials.

See the ACME documentation for full setup instructions including Traefik and acme.sh examples.

FAQ

I can not login

Make sure you are accessing VaulTLS using a secure connection i.e. HTTPS. If you want to access VaulTLS insecurely you need to add the following environmental variable: VAULTLS_INSECURE=true.

I (or a user) forgot my password

To change any users password specify the corresponding user's email address with the VAULTLS_ACCOUNT_EMAIL env variable and the new password with VAULTLS_ACCOUNT_PASSWORD. During start up VaulTLS will check for these and if set, adjust the password and exit. You can not use these env variables during normal operation and they need to be removed after the password was changed.

OIDC is not working

If VaulTLS claims that OIDC is not configured, the most likely cause is that it couldn't discover the OIDC provider based on the VAULTLS_OIDC_AUTH_URL given. Make sure the VaulTLS container can access the OIDC provider. In general the base url to the auth provider should be enough. For Authentik the required URL path is /application/o/<application slug>/. If that doesn't work, directly specify the .well_known url.

Mail is not working

Please make sure that you are choosing the correct email encryption type. Usually port 587 is for STARTTLS and 465 for TLS.

Roadmap

  • Allow user details to be updated
  • Improve testing

Install VaulTLS on Unraid in a few clicks.

Find VaulTLS in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for VaulTLS Review the template variables and paths Click Install

Related apps

Details

Repository
ghcr.io/7ritn/vaultls:latest
Last Updated2026-09-17
First Seen2026-09-17

Runtime arguments

Web UI
http://[IP]:[PORT:80]/
Network
bridge
Shell
sh
Privileged
false

Template configuration

WebUI PortPorttcp

Port for the web interface

Target
80
Default
5173
Value
5173
DataPathrw

Contains database, CA certificate and CRLs

Target
/app/data
Default
/mnt/user/appdata/vaultls
Value
/mnt/user/appdata/vaultls
VAULTLS_API_SECRETVariable

Required. Generate with: openssl rand -base64 32

VAULTLS_URLVariable

Public URL of this VaulTLS instance

Default
https://vaultls.example.com/
Value
https://vaultls.example.com/
VAULTLS_INSECUREVariable

Set to 'true' if you want to access without HTTPS (not recommended)

Default
false
Value
false
VAULTLS_DB_SECRETVariable

Optional: encrypts the database. Note: this is irreversible. Remove this variable if not needed to prevent startup errors.

VAULTLS_LOG_LEVELVariable

Log level: error, warn, info, debug, trace

Default
info
Value
info
VAULTLS_OIDC_AUTH_URLVariable

OIDC: base URL of your auth provider

VAULTLS_OIDC_CALLBACK_URLVariable

OIDC: callback URL, e.g. https://vaultls.example.com/api/auth/oidc/callback

VAULTLS_OIDC_IDVariable

OIDC: client ID

VAULTLS_OIDC_SECRETVariable

OIDC: client secret

VAULTLS_ACME_ENABLEDVariable

Set to 'true' to use VaulTLS as an ACME CA (e.g. for Traefik/acme.sh)

Default
false
Value
false