{"id":13521716,"url":"https://github.com/duyet/grant-rs","last_synced_at":"2025-04-14T13:32:52.587Z","repository":{"id":38020586,"uuid":"427605796","full_name":"duyet/grant-rs","owner":"duyet","description":"Manage Redshift/Postgres privileges in GitOps style written in Rust","archived":false,"fork":false,"pushed_at":"2024-09-27T03:24:35.000Z","size":1993,"stargazers_count":32,"open_issues_count":9,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-12T03:02:22.908Z","etag":null,"topics":["data-engineering","data-ops","gitops","hacktoberfest","postgres","redshift","rust"],"latest_commit_sha":null,"homepage":"https://duyet.github.io/grant-rs/grant/index.html","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duyet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"duyet","ko_fi":"duyet"}},"created_at":"2021-11-13T08:09:11.000Z","updated_at":"2024-12-15T00:50:30.000Z","dependencies_parsed_at":"2024-05-05T10:30:10.349Z","dependency_job_id":null,"html_url":"https://github.com/duyet/grant-rs","commit_stats":null,"previous_names":["duyet/grant.rs"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duyet%2Fgrant-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duyet%2Fgrant-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duyet%2Fgrant-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duyet%2Fgrant-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duyet","download_url":"https://codeload.github.com/duyet/grant-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248888682,"owners_count":21178093,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-engineering","data-ops","gitops","hacktoberfest","postgres","redshift","rust"],"created_at":"2024-08-01T06:00:37.456Z","updated_at":"2025-04-14T13:32:52.561Z","avatar_url":"https://github.com/duyet.png","language":"Rust","funding_links":["https://github.com/sponsors/duyet","https://ko-fi.com/duyet"],"categories":["Tools"],"sub_categories":[],"readme":"# grant-rs [![crates.io](https://img.shields.io/crates/v/grant.svg)](https://crates.io/crates/grant) [![Build \u0026 Test](https://github.com/duyet/grant-rs/actions/workflows/build-test.yaml/badge.svg)](https://github.com/duyet/grant-rs/actions/workflows/build-test.yaml)\n\nAn open-source project that aims to manage Postgres/Redshift database roles and privileges in GitOps style, written in Rust.\n\n[**Home**](https://github.com/duyet/grant-rs) | [**Documentation**](https://docs.rs/grant)\n\n_This project is still in the early stages of development and is not ready for any kind of production use or any alpha/beta testing._\n\n| Level      | Supported | Description                                                                                                                                                                                                                                            |\n| ---------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `DATABASE` |     ✓     | Support grant `CREATE`\\| `TEMP` \\| `ALL` on database(s) to user                                                                                                                                                                                        |\n| `SCHEMA`   |     ✓     | Support grant `CREATE` \\| `USAGE` \\| `ALL` on schema(s) to user                                                                                                                                                                                        |\n| `TABLE`    |     ✓     | Support grant `SELECT` \\| `INSERT` \\| `UPDATE` \\| `DELETE` \\| `DROP` \\| `REFERENCES` \\| `ALL` on tables(s) or `ALL` tables in schema(s) to user. \u003cbr\u003e Supported excluding table(s) by adding `-` before the table name (e.g. `tables: [ALL, -table]`). |\n| `FUNCTION` |           | Not supported yet                                                                                                                                                                                                                                      |\n\n\u003c!-- edit in https://www.tablesgenerator.com/markdown_tables --\u003e\n\n# Installation\n\nInstall via Homebrew:\n\n```bash\nbrew tap duyet/tap\nbrew install grant\n```\n\nOr, install binary from crates.io via Cargo. You will need to have Rust installed. You can get it by visiting [rustup.rs](https://rustup.rs). This'll also install Cargo, Rust's package/project manager.\n\n```bash\ncargo install grant\n```\n\n# Usage\n\nUsing `grant` tool:\n\n```bash\n$ grant --help\n\ngrant 0.0.1-beta.3\nManage database roles and privileges in GitOps style\n\nUSAGE:\n    grant \u003cSUBCOMMAND\u003e\n\nFLAGS:\n    -h, --help       Prints help information\n    -V, --version    Prints version information\n\nSUBCOMMANDS:\n    apply       Apply a configuration to a redshift by file name. Yaml format are accepted\n    gen         Generate sample configuration file\n    gen-pass    Generate random password\n    help        Prints this message or the help of the given subcommand(s)\n    inspect     Inspect current database cluster with connection info from configuration file\n    validate    Validate a configuration file or a target directory that contains configuration files\n```\n\n## Generate project structure\n\n```bash\ngrant gen --target ./cluster\n\nCreating path: \"./cluster\"\nGenerated: \"./cluster/config.yml\"\n```\n\n## Apply privilege changes\n\nContent of `./examples/example.yaml`:\n\n```yaml\nconnection:\n  type: \"postgres\"\n  # support environment variables, e.g. postgres://${HOSTNAME}:5432\n  url: \"postgres://postgres@localhost:5432/postgres\"\n\nroles:\n  - name: role_database_level\n    type: database\n    grants:\n      - CREATE\n      - TEMP\n    databases:\n      - postgres\n\n  - name: role_schema_level\n    type: schema\n    grants:\n      - CREATE\n    databases:\n      - postgres\n    schemas:\n      - public\n  - name: role_all_schema\n    type: table\n    grants:\n      - SELECT\n      - INSERT\n      - UPDATE\n    databases:\n      - postgres\n    schemas:\n      - public\n    tables:\n      - ALL # include all table\n      - +public_table # can add `+` to mark included tables (public.public_table)\n      - -secret_table # add `-` to exclude this table (public.secret_table)\n      - -schema2.table # exclude schema2.table\n\nusers:\n  - name: duyet\n    password: 1234567890 # password in plaintext\n    roles:\n      - role_database_level\n      - role_all_schema\n      - role_schema_level\n  - name: duyet2\n    password: md58243e8f5dfb84bbd851de920e28f596f # support md5 style: grant gen-pass -u duyet2\n    roles:\n      - role_database_level\n      - role_all_schema\n      - role_schema_level\n```\n\nApply this config to cluster:\n\n```bash\ngrant apply -f ./examples/example.yaml\n\n[2021-12-06T14:37:03Z INFO  grant::connection] Connected to database: postgres://postgres@localhost:5432/postgres\n[2021-12-06T14:37:03Z INFO  grant::apply] Summary:\n    ┌────────────┬────────────────────────────┐\n    │ User       │ Action                     │\n    │ ---        │ ---                        │\n    │ duyet      │ no action (already exists) │\n    │ duyet2     │ no action (already exists) │\n    └────────────┴────────────────────────────┘\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE, TEMP ON DATABASE postgres TO duyet;\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE ON SCHEMA public TO duyet;\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO duyet;\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE, TEMP ON DATABASE postgres TO duyet2;\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE ON SCHEMA public TO duyet2;\n[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO duyet2;\n[2021-12-12T13:48:22Z INFO  grant::apply] Summary:\n    ┌────────┬─────────────────────┬──────────────────────┬─────────┐\n    │ User   │ Role Name           │ Detail               │ Status  │\n    │ ---    │ ---                 │ ---                  │ ---     │\n    │ duyet  │ role_database_level │ database[\"postgres\"] │ updated │\n    │ duyet  │ role_schema_level   │ schema[\"public\"]     │ updated │\n    │ duyet  │ role_table_level    │ table[\"ALL\"]         │ updated │\n    │ duyet2 │ role_database_level │ database[\"postgres\"] │ updated │\n    │ duyet2 │ role_schema_level   │ schema[\"public\"]     │ updated │\n    │ duyet2 │ role_table_level    │ table[\"ALL\"]         │ updated │\n    └────────┴─────────────────────┴──────────────────────┴─────────┘\n```\n\n## Generate random password\n\n```bash\n$ grant gen-pass\n\nGenerated password: q)ItTjN$EXlkF@Tl\n```\n\n```bash\n$ grant gen-pass --user duyet\n\nGenerated password: o^b3aD1L$xLm%#~U\nGenerated MD5 (user: duyet): md58243e8f5dfb84bbd851de920e28f596f\n```\n\n## Inspect the current cluster\n\n```bash\n$ grant inspect -f examples/example.yaml\n\n[2021-11-29T07:46:44Z INFO  grant::inspect] Current users in postgres://postgres@localhost:5432/postgres:\n    ┌────────────┬──────────┬───────┬──────────┐\n    │ User       │ CreateDB │ Super │ Password │\n    │ ---        │ ---      │ ---   │ ---      │\n    │ postgres   │ true     │ true  │ ******** │\n    │ duyet      │ false    │ false │ ******** │\n    └────────────┴──────────┴───────┴──────────┘\n```\n\n# Developement\n\nClone the repo:\n\n```bash\ngit clone https://github.com/duyet/grant-rs \u0026\u0026 cd grant-rs\n```\n\nPostgres is required for testing, you might need to use the `docker-compose.yaml`:\n\n```bash\ndocker-compose up -d\n```\n\nMake sure you have connection to `postgres://postgres:postgres@localhost:5432/postgres`.\n\nOn the MacOS, the easiest way is install [Postgres.app](https://postgresapp.com).\n\nTo run the unittest:\n\n```bash\ncargo test\n```\n\n# Contributing\n\nI greatly appreciate if you have any ideas or make a PR to this project.\nThank you for contributing! \n\n# TODO\n\n- [x] Support reading connection info from environment variables\n- [x] Support store encrypted password in Git ([md5](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_USER.html))\n- [x] Support Postgres and Redshift\n- [x] Support change password (via: `users[*].update_password=true`)\n- [ ] Visuallization (who can see what?)\n- [ ] Apply show more detail about diff changes\n- [ ] Inspect show more detail about user privileges\n- [ ] Command to rotate passwords\n- [ ] Suport DROP users that not in the configuration (it's not safe to do it for now)\n\n# LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduyet%2Fgrant-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduyet%2Fgrant-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduyet%2Fgrant-rs/lists"}