Create a Database User & Grant Permissions
A copy-paste SQL generator for least-privilege user accounts. Pick your engine, fill in the details, and get correct, secure statements in one click.
Prefer to generate a password in your shell?
< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32; echo
Creating a dedicated, scoped user for every application is one of the highest-leverage things you can do for database security. This tool writes the exact statements for you — and below is a plain-English reference for how it works in each engine.
How to create a user in each database
The idea is the same everywhere — an identity, a password (or an OS/identity provider), and a narrow set of privileges — but the syntax differs. Here are the canonical patterns the generator produces.
MySQL & MariaDB
Identity is a user@host pair, so the same username from a different host is a different account.
Grant privileges per database, and only FLUSH PRIVILEGES if you edited the grant tables directly.
CREATE USER 'app_user'@'%' IDENTIFIED BY '••••••'; GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO 'app_user'@'%';
PostgreSQL
Roles are cluster-wide, so grant CONNECT on the database, USAGE on the schema, and
privileges on the tables. Client host/IP rules live in pg_hba.conf, not in SQL.
CREATE USER app_user WITH PASSWORD '••••••'; GRANT CONNECT ON DATABASE app_db TO app_user; GRANT USAGE ON SCHEMA public TO app_user; GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_user;
Oracle
A user is a schema. A new account needs CREATE SESSION before it can even log in, then
object or system privileges for data access.
CREATE USER app_user IDENTIFIED BY "••••••"; GRANT CREATE SESSION TO app_user; GRANT SELECT ON app_db.employees TO app_user;
SQL Server
Authentication (a server-level LOGIN) is separate from authorization (a database USER).
Membership in fixed roles like db_datareader is the idiomatic way to grant access.
CREATE LOGIN [app_user] WITH PASSWORD = '••••••'; USE [app_db]; CREATE USER [app_user] FOR LOGIN [app_user]; ALTER ROLE db_datareader ADD MEMBER [app_user];
IBM Db2
Db2 doesn't store passwords — it trusts the operating system (or LDAP/Kerberos). Create the OS account first, then grant it database privileges.
-- create the OS user first, then in Db2: GRANT CONNECT ON DATABASE TO USER app_user; GRANT SELECT ON TABLE app_db.employees TO USER app_user;
Which permissions does each preset grant?
The presets map to a real-world job. Start with the least-powerful preset that still lets the workload run.
| Preset | Use it for | Roughly grants |
|---|---|---|
| Read only | BI tools, analytics, read replicas of logic | SELECT |
| Backup / dump | mysqldump, pg_dump, exports | SELECT + lock/show/event |
| CRUD | Most web & API backends | SELECT, INSERT, UPDATE, DELETE |
| App / migrations | WordPress, Rails/Django/Laravel with migrations | CRUD + CREATE, ALTER, INDEX, DROP |
| Replication | Replica/standby accounts | REPLICATION SLAVE / WITH REPLICATION |
| Full / admin | Break-glass & DBA use only | ALL PRIVILEGES / DBA / sysadmin |
Not every engine supports every preset natively — for example, replication is a first-class grant in MySQL and PostgreSQL but a configuration workflow in SQL Server and Oracle. The tool disables presets that don't apply to the selected engine.
Security best practices
Least privilege
Grant only what the workload uses. A leaked read-only credential can't drop your tables.
One user per app
Separate accounts let you rate-limit, audit and rotate independently, and shrink the blast radius of a breach.
Strong, random passwords
Use 24+ random characters. This tool generates 32-character secrets locally in your browser.
Restrict the host
Prefer localhost or a specific IP/subnet over the % wildcard whenever the topology allows it.
Never ship admin creds
Applications should never connect as root, sa, SYSTEM or a superuser.
Rotate & store safely
Keep credentials in a secrets manager or vault, out of source control, and rotate on a schedule.
Monitor what those users do
Creating a separate account per application isn't just a security win — it's what makes database observability possible. Once each workload connects with its own user you can attribute every query, connection and lock to a real service, spot a runaway report before it takes down production, and see exactly who is hammering the database at 3 a.m. Least-privilege users and good monitoring are two halves of the same practice.
Percona Monitoring & Management
Free, open-source observability for MySQL, MariaDB, PostgreSQL and MongoDB. PMM ships per-user and per-query analytics (Query Analytics / QAN), so you can rank the heaviest queries by the account that ran them and catch missing indexes and lock contention early.
PostgreSQL
Start with the built-in pg_stat_activity and pg_stat_statements views to break
down load by role, then layer on tools like pganalyze or Prometheus +
postgres_exporter for dashboards and alerting.
Oracle & SQL Server
Oracle's AWR/ASH reports and Enterprise Manager profile activity by session and user. On SQL Server, the
dynamic management views (sys.dm_exec_*), Query Store and Extended Events do the same.
Audit the grants themselves
Monitoring isn't only about performance. Periodically review who holds which privileges — query
information_schema / pg_roles / DBA_SYS_PRIVS — and revoke access
that's no longer used. Least privilege drifts over time.
Manage users & grants as code
One-off SQL is great for learning and quick fixes, but for real infrastructure you want these accounts defined declaratively, peer-reviewed and version-controlled. Managing users as code means any environment is reproducible, drift is visible in a diff, and access changes go through the same review as the rest of your codebase.
See idempotent examples with the popular infrastructure & configuration-management tools:
Terraform →
Plan-and-apply user & grant resources for MySQL and PostgreSQL.
Ansible →
Agentless, push-over-SSH modules for creating users and grants.
Chef →
Ruby-based resources to declare users and privileges.
Puppet →
Declarative manifests for reproducible database access.
Want credentials that don't live in config at all? HashiCorp Vault's database secrets engine issues short-lived users on demand and drops them when the lease expires. Migration tools like Flyway and Liquibase, and Kubernetes operators (Percona, CloudNativePG), can manage grants too. The Terraform page covers these.
Frequently asked questions
Is my data safe — do the username and password leave my browser?
No. The entire generator runs client-side in JavaScript. Nothing you type and no generated statement is ever sent to a server. You can disconnect from the internet and it keeps working.
What's the difference between a MySQL user and a PostgreSQL/Oracle role?
In MySQL an account is a user@host pair scoped by connecting host. PostgreSQL and
Oracle use cluster/instance-wide roles (Postgres controls the connecting host separately in
pg_hba.conf). SQL Server splits it into a server LOGIN and a per-database
USER, and Db2 delegates authentication to the operating system entirely.
Why grant specific privileges instead of ALL PRIVILEGES?
Least privilege limits damage. If an app only reads data, a compromised credential (SQL injection, leaked config, stolen laptop) can't delete rows, drop tables or read other databases. It also makes auditing and troubleshooting far easier.
Do I need FLUSH PRIVILEGES in MySQL?
Only if you modified the grant tables directly with INSERT/UPDATE.
When you use CREATE USER and GRANT, MySQL reloads privileges automatically. It's
included as a harmless belt-and-suspenders line you can delete.
How do I create a read-only user for backups?
Pick your engine, choose the Backup / dump preset, and the tool adds the
extra privileges a consistent export needs (locking/showing views and events on MySQL, SELECT
across the schema on PostgreSQL, and so on).
Ship secure database access, every time
Bookmark this generator for the next time you stand up an app, a replica, or an analytics account — and wire it into your infrastructure-as-code once you're happy with the grants.
Back to the generator