Gratan
MySQLManage MySQL users, grants, and privileges as code
- Manages
- MySQL privileges
- Language
- Ruby
- Package
- gratan
- CLI
- gratan
- Config file
- Grantfile
user "scott", "%" do
on "*.*" do
grant "USAGE"
end
on "test.*", expired: '2014/10/08' do
grant "SELECT"
grant "INSERT"
end
on /^foo\.prefix_/ do
grant "SELECT"
grant "INSERT"
end
end
Gratan is a Ruby command-line tool that manages MySQL users, grants, and privileges as code. You export the current grants into a Grantfile, review edits as Git diffs, then apply them idempotently. A dry-run previews every GRANT and REVOKE before anything changes.
What is Gratan?
Gratan is a command-line tool. It manages MySQL users, grants, and privileges as code. Instead of running GRANT and REVOKE by hand on each server, you write the permissions you want in a Ruby file. This file is called a Grantfile. Gratan then changes MySQL to match it.
Old MySQL servers collect messy privileges over the years. Nobody recalls why a user can write to a schema, and there is no record of changes. Gratan fixes that. The Grantfile lives in Git, so every change is a diff you can review. It follows the standard codenization pattern:
- Export the grants that already exist.
- Review each edit as a Git diff.
- Dry-run to preview the plan, then apply.
Gratan suits DBAs and infrastructure engineers who already keep config in version control. Run PostgreSQL instead? Its sibling Posgra does the same job for Postgres roles and grants.
- Manages MySQL users, grants, and privileges from one Ruby DSL file.
- Config lives in a file named the Grantfile, kept in version control.
- A dry-run previews every grant and revoke, and applies are idempotent.
- Supports regex object matching and
expired:dates for time-limited access. - Related access-as-code tools include Miam for AWS IAM users and policies.
- The repository is archived (last active January 2024); the gem still runs.
Install and run Gratan
Install
Install the gratan gem (Ruby required).
$ gem install gratanExport current state
Pull the live MySQL configuration into a Grantfile.
$ gratan -e -o GrantfileDry-run, then apply
Preview the diff, then apply the change for real.
$ gratan -a --dry-runGratan uses the export, review, apply loop shared by the codenize-tools family. Start by exporting the live server with gratan -e. It writes every user and grant into a Grantfile. Big installs can be split into many files with --split or --chunk-by-user. Commit that file so your current privileges become a reviewed baseline.
To make a change, edit the Grantfile and run gratan -a --dry-run. Gratan compares the file to the server. It prints the exact GRANT and REVOKE steps it would take, but runs none of them. When the plan looks right, run gratan -a to apply. Applies are idempotent, so running the same file twice changes nothing. A scheduled dry-run also works as a simple drift check for your MySQL privileges.
Run a scheduled gratan -a --dry-run in CI. Any privilege someone added by hand on the server shows up as drift you can review before it becomes permanent.
What Gratan can do
Export existing privileges
The export command dumps every user and grant from a live server into the DSL. Use <code>--split</code> or <code>--chunk-by-user</code> to break big installs into several files.
Idempotent apply with dry-run
<code>gratan -a</code> makes the server match the Grantfile, and a second run does nothing. Add <code>--dry-run</code> to preview the exact grant and revoke steps first.
Regex object matching
Grant blocks accept regular expressions like <code>on /^foo\.prefix_/</code>. One rule can then cover every table that matches a naming pattern.
Grant expiration dates
Users and grants can carry an <code>expired:</code> date. Time-limited access becomes explicit and reviewable instead of relying on memory.
Templates for repeated grants
Since version 0.3.0, <code>template</code> and <code>include_template</code> define a privilege set once. You reuse it across users with per-inclusion values.
Scoping and filter flags
<code>--ignore-user</code>, <code>--target-user</code>, and <code>--ignore-object</code> take regexes. System accounts or specific schemas can be left out of management.
| Privilege | What it allows |
|---|---|
USAGE | No real access; marks that the user exists |
SELECT | Read rows from tables or views |
INSERT | Add new rows |
UPDATE | Change existing rows |
DELETE | Remove rows |
ALL PRIVILEGES | Every privilege on the chosen object |
When teams reach for Gratan
Auditable privilege reviews
Keep the Grantfile in Git and every change becomes a pull request. Reviewers read the diff instead of querying <code>mysql.user</code>, and <code>git blame</code> shows who granted what.
Environment parity
Export grants from production, commit them, and apply the same Grantfile to staging. Gaps between environments show up as dry-run output, not surprise permission errors.
Time-limited access
Grant a contractor <code>SELECT</code> with an <code>expired:</code> date attached. The expiration is visible in review, and the grant does not outlive the work.
Taming inherited servers
On a legacy database, one export gives you a full inventory of grants. From there you prune unused accounts in small, dry-run-checked steps.