{"id":15060834,"url":"https://github.com/wegel/shghr","last_synced_at":"2026-02-02T16:08:44.029Z","repository":{"id":247845747,"uuid":"827004217","full_name":"wegel/shghr","owner":"wegel","description":"Secure Self-Hosted Github Runner","archived":false,"fork":false,"pushed_at":"2025-04-10T02:00:26.000Z","size":36,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-18T21:45:52.393Z","etag":null,"topics":["fsharp","github","github-runner","libvirtd","podman","rootless-podman"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wegel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE.txt","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}},"created_at":"2024-07-10T20:27:40.000Z","updated_at":"2025-04-10T02:00:29.000Z","dependencies_parsed_at":"2025-01-21T22:10:25.399Z","dependency_job_id":"b438b123-f8e4-46a3-b6ee-3bbf433a91ea","html_url":"https://github.com/wegel/shghr","commit_stats":null,"previous_names":["wegel/secure-github-self-hosted-runner","wegel/shghr-secure-self-hosted-github-runner"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/wegel/shghr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wegel%2Fshghr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wegel%2Fshghr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wegel%2Fshghr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wegel%2Fshghr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wegel","download_url":"https://codeload.github.com/wegel/shghr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wegel%2Fshghr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29015145,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T14:58:54.169Z","status":"ssl_error","status_checked_at":"2026-02-02T14:58:51.285Z","response_time":58,"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":["fsharp","github","github-runner","libvirtd","podman","rootless-podman"],"created_at":"2024-09-24T23:05:15.790Z","updated_at":"2026-02-02T16:08:44.010Z","avatar_url":"https://github.com/wegel.png","language":"F#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# shghr (pronouned \"Sugar\")\n\n## (Secure) Self-hosted GitHub Runner\n\n## The Problem\n\n[GitHub's documentation states](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security):\n\n\u003e We recommend that you only use self-hosted runners with private repositories. This is because forks of\n\u003e your public repository can potentially run dangerous code on your self-hosted runner machine by creating\n\u003e a pull request that executes the code in a workflow.\n\u003e\n\u003e This is not an issue with GitHub-hosted runners because each GitHub-hosted runner is always a clean isolated\n\u003e virtual machine, and it is destroyed at the end of the job execution.\n\n## The Solution\n\nStarting something on-demand for every job is not that hard... So, why don't we do exactly that ourselves?\n\nThis is precisely what this project accomplishes.\n\nWith Secure GitHub Self-Hosted Runner, it's now safe to run a self-hosted runner for a public repository.\n\n## How It Works\n\nThis project provides a solution by:\n\n1. Monitoring GitHub workflows and jobs using the GitHub API.\n2. When a job needs to be executed, the main program calls the appropriate executor.\n3. The executor's `prepare` stage sets up the environment, typically starting a GitHub Runner instance.\n4. Once the environment is ready, the main program calls the executor's `run` stage to execute the job.\n5. After the job is completed, the main program calls the executor's `cleanup` stage to destroy the environment.\n\nThe main program performs two primary functions:\n- Monitors for jobs that need to be run.\n- Calls the executor's scripts (`prepare`, `run`, `cleanup`) with the appropriate environment variables gathered from the GitHub API.\n\n## Key Features\n\n- Isolated Execution: Each job runs in a clean, isolated environment.\n- On-Demand Environments: Execution environments are created only when needed and destroyed after use.\n- Rootless Containers: Enhanced security through rootless container execution.\n- Flexible Executors: Support for different execution environments.\n- Pre-Execution Filtering: Opportunity to examine and filter jobs before execution.\n\n## Executors\n\nExecutors are responsible for preparing, running, and cleaning up the environment for each job. A key security feature of our executors is the use of rootless podman, ensuring that no part of the execution process has root access to the system.\n\nCurrently, we support two types of executors:\n\n1. rootless `podman-in-podman`: This executor uses nested containerization, running the GitHub Runner in a nested rootless podman container.\n2. rootless `libvirtd-in-podman`: This executor runs the GitHub Runner in a freshly booted virtual machine using libvirtd/qemu from within a rootless podman container.\n\nBoth executors leverage rootless podman, providing an additional layer of security by ensuring that the execution environment has no root access to the host system.\n\nEach executor consists of three main scripts:\n\n- `prepare.sh`: Sets up the execution environment, typically starting a GitHub Runner instance.\n- `run.sh`: Executes the job within the prepared environment.\n- `clean.sh`: Cleans up and destroys the environment after job completion.\n\nThe main program calls these scripts as needed for each job execution, passing the appropriate environment variables.\n\n### Adding New Executors\n\nThe system is designed to be extensible. New executors can be added as needed by creating the three required scripts (`prepare.sh`, `run.sh`, and `clean.sh`) and integrating them into the main program. This flexibility allows for adaptation to various execution requirements and environments. When adding new executors, it's recommended to maintain the principle of using rootless containers to ensure consistent security across all execution methods.\n\n## Security Advantages\n\nOur process includes a pre-execution phase where we can examine workflow and job details, including the account requesting the job. This enables:\n\n- Whitelisting of allowed accounts\n- Filtering based on workflow or job information\n- Custom security rules as defined by the administrator\n\nAdditionally, the use of rootless podman in our executors ensures that the execution environment has no root access to the host system, significantly enhancing overall security.\n\n## Getting Started\n\n```\nEXECUTOR=executors/libvirtd-in-podman GITHUB_TOKEN=mytoken REPO=https://github.com/owner/reponame make run\n```\n\n## License\n\nThis project is dual-licensed:\n\n1. For personal or non-commercial use:\n   This project is licensed under the Apache License 2.0. See the [LICENSE-APACHE.txt](LICENSE-APACHE.txt) file for details.\n\n2. For commercial use:\n   A commercial license is required. Please contact me to obtain a commercial license. See the [LICENSE-COMMERCIAL.md](LICENSE-COMMERCIAL.md) file for details.\n\nBy using this software, you agree to the terms of one of these licenses.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwegel%2Fshghr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwegel%2Fshghr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwegel%2Fshghr/lists"}