{"id":18603068,"url":"https://github.com/devlooped/gh-sponsors","last_synced_at":"2025-05-16T18:13:26.959Z","repository":{"id":188291613,"uuid":"678440494","full_name":"devlooped/gh-sponsors","owner":"devlooped","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-15T00:20:26.000Z","size":131,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-01T09:37:16.029Z","etag":null,"topics":["gh-extension"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":false,"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/devlooped.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"license.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},"funding":{"github":"devlooped"}},"created_at":"2023-08-14T14:58:47.000Z","updated_at":"2024-05-08T01:26:34.201Z","dependencies_parsed_at":"2024-04-15T01:36:33.915Z","dependency_job_id":null,"html_url":"https://github.com/devlooped/gh-sponsors","commit_stats":null,"previous_names":["kzu/gh-sponsors","devlooped/gh-sponsors"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2Fgh-sponsors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2Fgh-sponsors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2Fgh-sponsors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2Fgh-sponsors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devlooped","download_url":"https://codeload.github.com/devlooped/gh-sponsors/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254582912,"owners_count":22095519,"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":["gh-extension"],"created_at":"2024-11-07T02:13:23.867Z","updated_at":"2025-05-16T18:13:26.935Z","avatar_url":"https://github.com/devlooped.png","language":"C#","funding_links":["https://github.com/sponsors/devlooped"],"categories":[],"sub_categories":[],"readme":"# ![](https://github.com/devlooped/SponsorLink/raw/main/assets/img/sponsorlink-32.png) GitHub Sponsors CLI Extension\n\nAn extension to the [GitHub CLI](https://cli.github.com/) to manage your \nsponsorships, sync your [SponsorLink](https://github.com/devlooped/SponsorLink) \nmanifest and more.\n\n## Installation\n\nThe [GitHub CLI](https://cli.github.com/) must be installed first. \n\nInstall:\n\n```shell\ngh extension install devlooped/gh-sponsors\n```\n\nUpgrade:\n\n```shell\ngh extension upgrade sponsors\n```\n\nUninstall:\n\n```shell\ngh extension remove sponsors\n```\n\nThe extension uses the [GitHub CLI API](https://cli.github.com/manual/gh_api) to \nissue sponsors-related queries and render them to the console.\n\n\n## Usage\n\nThe extension adds a `sponsors` command to the `gh` CLI, which you can use to\nmanage your sponsorships and sync your SponsorLink manifest.\n\nAvailable commands: \n\n* `gh sponsors check \u003cuser/org\u003e \u003csponsorable\u003e`: checks if the current manifest \n  contains an active sponsorship from the specified user or organization to the \n  given sponsorable account.\n* `gh sponsors list`: list your current sponsorships.\n* `gh sponsors sync`: generate and sign your SponsorLink manifest. It requires \n  signing-in with your GitHub account both on the CLI and on github.com to authenticate \n  with SponsorLink backend for signing.\n* `gh sponsors validate`: checks if the current manifest is valid and not expired.\n* `gh sponsors remove`: removes all associated environment variables and backend \n  information for the current user.\n* `gh sponsors view`: view the backend information for the current user, as \n  claims provided by Auth0 after authenticating with your GitHub account, which \n  is the only information kept.\n\n\u003e NOTE: running `gh sponsors` invokes the `sync` command.\n\n## Issues\n\nPlease report issues on the [devlooped/SponsorLink](https://github.com/devlooped/SponsorLink/issues) \nrepository.\n\n## How it works\n\nAs a GitHub CLI extension, SponsorLink leverages your currently authenticated user \nto locate your personal sponsorships, as well as your organizations'. It does this \nentirely locally, communicating exclusively with the GitHub API itself. \n\nFor example, it runs the following GraphQL query to retrieve your active sponsorships:\n\n```graphql\nquery { \n    viewer { \n        sponsorshipsAsSponsor(activeOnly: true, first: 100) {\n            nodes {\n                sponsorable {\n                    ... on Organization {\n                        login\n                    }\n                    ... on User {\n                        login\n                    }\n                }        \n            }\n        }\n    }\n}\n```\n\nYou can run these same queries on the [GitHub GraphQL Explorer](https://docs.github.com/en/graphql/overview/explorer).\n\nThis information is used to locally create a [JWT token](https://jwt.io/) with \n[hash claims](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes.hash?view=net-7.0) \ncalculated as: `base64(sha256(salt+user/org+sponsored))`.\n\nThe random salt is initialized to a GUID the first time you run this extension. \nOnce hashed, the values are entirely opaque. Packages can use this JWT manifest \nto check (entirely offline) for hashed claims matching the salt + current user + \nsponsorable account to check for.\n\nWhen the manifest is generated or synchronized (manually and explicitly when the \n`gh sponsors` command is run), it is sent our backend \n([open source at SponsorLink](https://github.com/devlooped/SponsorLink)) \npurely for signing with SponsorLink's private key. This allows consumers to verify \n(offline) the integrity of the manifest, even though it doesn't convey any private \ninformation.\n\nThe only bit of personally identifiable information that is sent to our backend with \nthe JWT token is the GitHub user identifier (an integer like `169707`) which you authorize \nas part of authenticating with your GitHub account to our backend API (we use Auth0 for this). \nThis identifier is already public for everyone on GitHub (i.e. see \n[dependabot-bot](https://api.github.com/users/dependabot-bot) or \n[dependabot org](https://api.github.com/orgs/dependabot)).\n\nPlease read the full [privacy policy](privacy.md) for more information.\n\n### Implementation details\n\nAfter the first sync (and accepting the usage terms), the following environment \nvariables are populated:\n\n* `SPONSORLINK_INSTALLATION`: a random GUID used for salting hashes.\n* `SPONSORLINK_MANIFEST`: the JWT token with hashed claims for your current \n  sponsorships.\n* `SPONSORLINK_TOKEN`: last used access token to invoke SponsorLink backend \n  JWT signing API. Issued by Auth0 after authenticating with your GitHub account \n  on github.com.\n\nPublic key for validating the manifest (paste in one-line): \n\n```text\nMIIBCgKCAQEAo5bLk9Iim5twrxGVzJ4OxfxDuvy3ladTNvcFNv4Hm9/1No89SISKTXZ1bSABTnq\nH6z/DpklcHveGMSmsncEvUebrg7tX6+M3byVXU6Q/d82PtwgbDXT9d10A4lePS2ioJQqlHWQy/f\nuNwe7FjptV+yguf5IUxVRdZ77An1IyGUk9Cj6n4RuYIPrP5O0AmFPHOwEzywUWVaV1NHYRe0Th6\ni5/hyDV13K7+LP9VzwucnWEvzujtnL6ywZDeaKkwfeFsXZyYywHj6oJK9Obed/nu1e+69fmUqpr\ntc0t/3A9uHc0G/0sDNLLAd83j2NSOS2IHJo17azOLFuhekka8dSKnQIDAQAB\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlooped%2Fgh-sponsors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevlooped%2Fgh-sponsors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlooped%2Fgh-sponsors/lists"}