See CHANGELOG.md for version history.
A security-focused Go CLI tool for safely creating paired MariaDB databases and users.
This tool is designed with a fail-closed philosophy:
If anything unexpected exists, nothing is modified.
- Fail Closed --- If either the database or user already exists, creation is aborted.
- Idempotent --- Safe to run repeatedly.
- Deterministic Naming --- Domain inputs are normalized into valid identifiers.
- No Partial State --- If creation fails mid-process, cleanup is automatically performed.
- No Secrets in Logs --- Passwords are never written to logs.
- Separate checks for database and user existence
- Strict input validation
- Optional domain name normalization (enabled by default)
- Wildcard host (
%,_) disabled by default - Automatic rollback if
CREATE USERorGRANTfails - Timeout protection for DB operations
- XDG-compliant configuration and state handling
With -normalize (enabled by default):
example.com → example_com
shop.example.io → shop_example_io
Invalid inputs (e.g. invalid name!!) are rejected.
Maximum identifier length is 64 characters.
Long names are truncated with a short hash suffix.
- 20 characters
- Alphanumeric + selected symbols
- Safe for SQL literals
- Single creation (
-c) - Batch mode (
-f) - Dry-run mode (
-dry-run) - Config initialization (
-i) - Optional credential export (
-export-csv)
go build -o mariadb-toolInitialize configuration:
./mariadb-tool -iCreate a single database/user:
./mariadb-tool -c example.comDry run:
./mariadb-tool -dry-run -c example.comBatch processing:
./mariadb-tool -f list.txtAllow wildcard host (explicit opt-in):
./mariadb-tool -allow-wildcard-host -user-host "%" -c example.comThe tool follows the XDG Base Directory Specification.
Unless overridden via flags:
Config
~/.config/mariadb-tool/config.ini
Logs
~/.local/state/mariadb-tool/error.log
CSV Export
~/.local/share/mariadb-tool/accounts.csv
No files are written to the current working directory unless explicitly specified.
Plain text, one entry per line:
example.com
shop.example.com
test-site.io
Comments (# or ;) and blank lines are ignored.
config.ini:
[mariadb]
username=admin
password=your_secure_password
hostname=localhost
port=3306The file is created with 0600 permissions.
Logs:
- Validation failures
- SQL errors
- Skipped operations
- Batch line numbers
- Configuration or connection errors
Passwords are never logged.
Credentials are exported only when -export-csv is used.
Format:
Timestamp Database Username Password
2026-02-19 14:27 example_com example_com 3oJb39NT90YaAx1c&wI6
The file is created with 0600 permissions.
This tool:
- Does not overwrite existing users
- Does not modify existing databases
- Does not escalate privileges
- Does not allow wildcard hosts unless explicitly enabled
- Cleans up partially created resources on failure
- Does not leak credentials to logs
It is intended for administrative automation, not multi-tenant self-service.
Tested against MariaDB using isolated Docker environments.
- CI (
.github/workflows/ci.yml) runs on push tomainand pull requests (go vet,go test ./...). - Integration (
.github/workflows/integration.yml) runs nightly and can also be started manually from GitHub Actions. - Release (
.github/workflows/release.yml) runs on tag pushes (v*) and publishes cross-platform build archives to the GitHub release.
- Issue templates are available for bug reports and feature requests (
.github/ISSUE_TEMPLATE/). - Pull requests use a default review checklist (
.github/pull_request_template.md). - Maintainer process and release operations are documented in
MAINTAINING.md.
Run unit tests:
go test ./...Run integration test (requires Docker):
MARIADB_TOOL_INTEGRATION=1 go test ./... -run TestProcessDatabaseMariaDBIntegration -count=1Run integration test against local MariaDB (localhost):
MARIADB_TOOL_LOCAL_INTEGRATION=1 \
MARIADB_TOOL_LOCAL_DSN='root:your_password@tcp(127.0.0.1:3306)/' \
go test ./... -run TestProcessDatabaseLocalMariaDBIntegration -count=1Scenarios verified:
- Normal creation
- Existing DB
- Existing user
- Privilege failure with automatic rollback
- Invalid input rejection
- Wildcard host enforcement
- XDG-compliant file placement
GNU General Public License v3.0 or later (GPL-3.0-or-later).
See the LICENSE file for details.
Provided as-is without warranty.
Always test against a staging environment before production use.