{"id":41772675,"url":"https://github.com/lirlia/prel","last_synced_at":"2026-01-25T03:16:37.786Z","repository":{"id":214375500,"uuid":"736096854","full_name":"lirlia/prel","owner":"lirlia","description":"prel(iminary) is an application that temporarily assigns Google Cloud IAM Roles and includes an approval process.","archived":false,"fork":false,"pushed_at":"2026-01-18T22:55:13.000Z","size":1745,"stargazers_count":45,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-19T08:23:26.149Z","etag":null,"topics":["google-cloud","governance-operations","iam-role","oss","security-tools","workflow"],"latest_commit_sha":null,"homepage":"","language":"Go","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/lirlia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-27T01:30:44.000Z","updated_at":"2026-01-18T16:38:00.000Z","dependencies_parsed_at":"2023-12-27T18:47:49.105Z","dependency_job_id":"42a2a879-f039-420f-85d6-e9b8083c9efa","html_url":"https://github.com/lirlia/prel","commit_stats":{"total_commits":84,"total_committers":3,"mean_commits":28.0,"dds":"0.40476190476190477","last_synced_commit":"85eeb197d7642a6662670c7a87c20079f0a2ac2e"},"previous_names":["lirlia/prel"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/lirlia/prel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirlia%2Fprel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirlia%2Fprel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirlia%2Fprel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirlia%2Fprel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lirlia","download_url":"https://codeload.github.com/lirlia/prel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirlia%2Fprel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28742973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T02:46:29.005Z","status":"ssl_error","status_checked_at":"2026-01-25T02:44:29.968Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["google-cloud","governance-operations","iam-role","oss","security-tools","workflow"],"created_at":"2026-01-25T03:16:37.726Z","updated_at":"2026-01-25T03:16:37.772Z","avatar_url":"https://github.com/lirlia.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003eprel\u003c/h1\u003e\n\n[![test wrapper](https://github.com/lirlia/prel/workflows/test%20wrapper/badge.svg)](https://github.com/lirlia/prel/actions?query=workflow:\"test+wrapper\")\n[![GitHub tag](https://img.shields.io/github/tag/lirlia/prel?include_prereleases=\u0026sort=semver\u0026color=blue)](https://github.com/lirlia/prel/releases/)\n[![License](https://img.shields.io/badge/License-MIT-blue)](#license)\n\n**This repository is in the experimental stage.**\n\n**Non-backward compatible changes may be made frequently.**\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"300px\" src=\"images/preln.png\"\u003e\n\u003c/p\u003e\n\n**prel**(iminary) is an application that temporarily assigns Google Cloud IAM Roles and includes an approval process.\n\nIt is inspired by [Qray](https://engineering.mercari.com/blog/entry/sre-qray/) from merpay.\n\n\u003ckbd\u003e![Alt text](images/request-form-0.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\n**Table Of Contents**\n\n- [Request Sequence](#request-sequence)\n- [Getting Started](#getting-started)\n- [How to use](#how-to-use)\n  - [1. Sign in by Google Account as `Requester`](#1-sign-in-by-google-account-as-requester)\n  - [2. Send Request as `Requester`](#2-send-request-as-requester)\n  - [3. Judge the Request as `Judger`](#3-judge-the-request-as-judger)\n  - [4. Invite new user as `Requester`](#4-invite-new-user-as-requester)\n  - [5. Approve Request as `Judger`](#5-approve-request-as-judger)\n  - [6. Check Google Cloud IAM setting](#6-check-google-cloud-iam-setting)\n- [How to Deploy](#how-to-deploy)\n- [`prel` Details](#prel-details)\n  - [User Roles](#user-roles)\n  - [User Management](#user-management)\n    - [Invitation](#invitation)\n    - [User Available](#user-available)\n- [Running the tests](#running-the-tests)\n- [Contributing](#contributing)\n- [Versioning](#versioning)\n- [License](#license)\n- [FAQ](#faq)\n  - [Why don't basic roles appear in the role list?](#why-dont-basic-roles-appear-in-the-role-list)\n  - [Why are some expected roles not listed?](#why-are-some-expected-roles-not-listed)\n  - [What should be stored in the secret manager?](#what-should-be-stored-in-the-secret-manager)\n  - [I can't sign-in locally due to a `Invalid Argument` error](#i-cant-sign-in-locally-due-to-a-invalid-argument-error)\n\n\u003cbr\u003e\n\n## Request Sequence\n\n```mermaid\nsequenceDiagram\nactor Requester\nactor Judger\nparticipant PreliminarySystem as prel\nparticipant NotificationSystem as Slack\nparticipant CloudService as Google Cloud\n    Requester -\u003e\u003e PreliminarySystem: Submit Request\n    PreliminarySystem -\u003e\u003e NotificationSystem: Send Notification\n    Judger -\u003e\u003e PreliminarySystem: Approve Request\n    PreliminarySystem -\u003e\u003e CloudService: Assign IAM Roles to Requester\n    PreliminarySystem -\u003e\u003e NotificationSystem: Send Notification\n    Requester -\u003e\u003e CloudService: Access with New Permissions\n```\n\n\u003cbr\u003e\n\n## Getting Started\n\n- [start manual](/docs/getting-started-manual.md)\n\n## How to use\n\n\u003e [!CAUTION]\n\u003e image is not latest.\n\n### 1. Sign in by Google Account as `Requester`\n\nLog in with your Google Account.\n\nThis user will be referred to as the **requester**. If login fails, review the OAuth consent settings.\n\n\u003cp align=\"center\"\u003e\n  \u003ckbd\u003e\u003cimg src=\"images/signin.png\"\u003e\u003c/kbd\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\nAfter logging in, a request form will appear.\n\n\u003ckbd\u003e![Alt text](images/request-form-1.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\n### 2. Send Request as `Requester`\n\nSelect the Project ID, and a list of available Roles for that project will appear.\n\nPlease select the necessary Roles (multiple selections possible).\n\n\u003ckbd\u003e![Alt text](images/request-form-2.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\nSet the Period to `1h` for subsequent work.(If the time is too short, the request will expire)\n\nOnce finished, press the Request button. You will then be redirected to the Pending page.\n\n\u003ckbd\u003e![Alt text](images/pending-request.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\nAt this time, a notification is sent to Slack.\n\n\u003cp align=\"center\"\u003e\n  \u003ckbd\u003e\u003cimg src=\"images/slack-new-request.png\"\u003e\u003c/kbd\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n### 3. Judge the Request as `Judger`\n\nSign in to http://localhost:8181 with a different browser (not sharing the session).\n\nThis user will be referred to as the **judger**.\n\n\u003cbr\u003e\n\nA `Not Invited` error will appear.\n\nIn this app, an invitation is mandatory for all users after the first registered user.\n\n\u003cp align=\"center\"\u003e\n  \u003ckbd\u003e\u003cimg src=\"images/not-invited.png\"\u003e\u003c/kbd\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n### 4. Invite new user as `Requester`\n\nNow, return to the **requester's** screen and access http://localhost:8181/admin/user.\n\nAn invitation input area will be at the top right, where you should enter the **judger's** email address.\n\n\u003ckbd\u003e![Alt text](images/user-management.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\nAt this point, set the permission to `judger` and then press the Invite button.\n\n\u003cp align=\"center\"\u003e\n  \u003ckbd\u003e\u003cimg src=\"images/invitation.png\"\u003e\u003c/kbd\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n### 5. Approve Request as `Judger`\n\nThen, re-login as the **judger** and access http://localhost:8181/request.\n\nYou will see options to Approve / Reject. Let's try Approving.\n\n\u003ckbd\u003e![Alt text](images/pending-request-judge.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\n### 6. Check Google Cloud IAM setting\n\nIf you have the correct Google Cloud permissions, [IAM](https://console.cloud.google.com/iam-admin/iam) will be updated with time condition.\n\n\u003ckbd\u003e![Alt text](images/iam.png)\u003c/kbd\u003e\n\n\u003cbr\u003e\n\nand a notification will be sent to Slack.\n\n\u003cp align=\"center\"\u003e\n  \u003ckbd\u003e\u003cimg src=\"images/slack-judge.png\"\u003e\u003c/kbd\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## How to Deploy\n\n- [deploy manual](/docs/deploy-manual.md)\n\n\u003cbr\u003e\n\n## `prel` Details\n\n### User Roles\n\n| role \\ action | request | judge(approve/reject) | delete own request\u003cbr\u003e(only pending status) | delete others request\u003cbr\u003e(only pending status) | judge own request |\n| :-----------: | :-----: | :-------------------: | :-----------------------------------------: | :--------------------------------------------: | :---------------: |\n|   requester   |   ⭕️    |           -           |                     ⭕️                      |                       -                        |         -         |\n|    judger     |   ⭕️    |          ⭕️           |                     ⭕️                      |                       -                        |         -         |\n|     admin     |   ⭕️    |          ⭕️           |                     ⭕️                      |                       ⭕️                       |         -         |\n\nuser invitation can only admin role.\n\n\u003cbr\u003e\n\n### User Management\n\n#### Invitation\n\nThe first user to sign-in becomes an `Admin Role`, and thereafter, an invitation is required for participation.\n\n**The email address of the Google Account** is needed for the invitation. Please note that no notifications, such as email, are sent; after inviting, the administrator should inform the invitee.\n\n**Regular expressions, Google Groups, service accounts, or other non-user principals are not supported.**\n\nThe invitation is valid for `7 days`. If this period is exceeded, the invitation becomes invalid and must be re-invited.\n\n---\n\n#### User Available\n\nThis setting enables or disables users. Disabled users cannot sign-in or perform any operations.\n\nRe-enabling allows them to operate again.\n\n## Running the tests\n\n```bash\nmake test\n```\n\nprel has following tests.\n\n- unit test\n- integration test\n- e2e test\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning.\n\nFor the versions available, see the [tags on this repository](https://github.com/lirlia/prel/tags).\n\n## License\n\nReleased under [MIT](/LICENSE) by [@lirlia](https://github.com/lirlia).\n\n## FAQ\n\n### Why don't basic roles appear in the role list?\n\nIn Google Cloud, Role Binding using IAM Conditions for basic roles is not permitted, so they are not displayed.\n\n\u003cbr\u003e\n\n### Why are some expected roles not listed?\n\nThis could be due to any of the following reasons:\n\n- The role is not appearing because the API in Google Cloud is not enabled (for example, if the Spanner API is disabled, Spanner Roles will not be displayed).\n- The role is not among the [grantable roles](https://cloud.google.com/iam/docs/viewing-grantable-roles?hl=en) in the target project.\n- The role name partially matches `[sS]erviceAgent` (these roles are only assignable to service accounts and are therefore not displayed).\n\n\u003cbr\u003e\n\n### What should be stored in the secret manager?\n\n- client secret\n- notification url\n\n\u003cbr\u003e\n\n### I can't sign-in locally due to a `Invalid Argument` error\n\nThis is likely due to a discrepancy caused by deleting the database while the browser still retains cookies.\n\nPlease delete the cookies for this app.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flirlia%2Fprel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flirlia%2Fprel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flirlia%2Fprel/lists"}