{"id":16446726,"url":"https://github.com/ffflabs/cf-badger","last_synced_at":"2026-01-20T13:02:16.325Z","repository":{"id":40701397,"uuid":"405584275","full_name":"ffflabs/cf-badger","owner":"ffflabs","description":"CF-Badger creates public urls displaying workflow statuses for your private repos without exposing your personal access token.","archived":false,"fork":false,"pushed_at":"2023-01-07T11:21:21.000Z","size":2131,"stargazers_count":2,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-08T05:45:44.383Z","etag":null,"topics":["cloudflare-workers","github-actions","github-api","status-badge","typescript"],"latest_commit_sha":null,"homepage":"https://cf-badger.com","language":"TypeScript","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/ffflabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-12T08:09:32.000Z","updated_at":"2023-03-10T12:10:28.000Z","dependencies_parsed_at":"2023-02-07T00:46:36.528Z","dependency_job_id":null,"html_url":"https://github.com/ffflabs/cf-badger","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ffflabs/cf-badger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffflabs%2Fcf-badger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffflabs%2Fcf-badger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffflabs%2Fcf-badger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffflabs%2Fcf-badger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ffflabs","download_url":"https://codeload.github.com/ffflabs/cf-badger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffflabs%2Fcf-badger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28603405,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T12:01:53.233Z","status":"ssl_error","status_checked_at":"2026-01-20T12:01:46.545Z","response_time":117,"last_error":"SSL_read: 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":["cloudflare-workers","github-actions","github-api","status-badge","typescript"],"created_at":"2024-10-11T09:48:38.979Z","updated_at":"2026-01-20T13:02:16.300Z","avatar_url":"https://github.com/ffflabs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp;[![Logo](logo.svg)](https://cf-badger.com/) \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp;\n\n[Cf-Badger](https://cf-badger.com) generates short urls displaying current status (actually, delayed up to 5 min) of your private repos workflows without exposing but the bare minimum of your code.\n \n\u003cp align=\"center\" style=\"text-align:center\"\u003e\n\u003ca href=\"https://workers.cloudflare.com/\"\u003e\n\u003cimg src=\"docs/images/cf-workers-badge.svg\"\u003e\u003c/a\u003e\n\u0026nbsp; \n\u003ca href=\"https://github.com/ffflabs/cf-badger/actions/workflows/test.yml\"\u003e\n\u003cimg src=\"https://cf-badger.com/badger/_39bde4f39ee9a2140d3a/endpoint.svg?branch=master\u0026style=for-the-badge\"\u003e\n\u003c/a\u003e\u0026nbsp; \n\u003ca href=\"https://pages.cloudflare.com/\"\u003e\n\u003cimg src=\"docs/images/cf-pages-badge.svg\"\u003e\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/static/v1?label=Made%20With\u0026message=TypeScript\u0026color=f0f0f0\u0026labelColor=3974c0\u0026style=for-the-badge\u0026logo=typescript\u0026logoColor=white\u0026messageColor=3974c0\"\u003e\n\n\u003cdiv align=\"center\" style=\"text-align:center\"\u003e\u003ca href=\"https://cf-badger.com\"\u003eCF-Badger\u003c/a\u003e is my project for the \u003ca href=\"https://challenge.developers.cloudflare.com/\"\u003eCloudflare Developer Summer Challenge\u003c/a\u003e\u003c/div\u003e\n\n\u003c/p\u003e \n\n[![CodeQL](https://cf-badger.com/badger/_b14dff568bb84d2bfe80/endpoint.svg?branch=master\u0026style=for-the-badge)](https://github.com/ffflabs/cf-badger/actions/workflows/codeql-analysis.yml)\n\n[![Deploy_Development](https://cf-badger.com/badger/_37f5d792a59297163894/endpoint.svg?branch=develop\u0026style=for-the-badge)](https://github.com/TreidSPA/api.mydot.app/actions/workflows/sentry_deploy_dev.yml)\n\n## 💥 Private Repos vs Public Badges. That's our pain point\n\nStatus badges are awesome. What's not to love about a self contained, colorful piece of relevant info?\n\nThe visual cue you get from a status badge conveys valuable info well beyond the specific concerns of development teams. However, it isn't possible to:\n\n  -  make them visible to other people in your company unless they are given permission over the repo itself.\n  -  embed them on wikis or dashboards, unless the repo is made public \n  -  having an accurate preview your README.md\n  -  use Shields.io's excellent service\n  \nBasically, any road that aims to preserve the code's private nature leads to broken badge images.\n\n\u003cp align=\"center\" style=\"text-align:center\"\u003e\n\n\n\u003cimg src=\"docs/images/before_and_after200.svg\"\u003e\n\n\u003cdiv align=\"center\" style=\"font-size:0.8em;text-align:center\"\u003eHow to get from broken to flawless?\u003c/div\u003e\n\n\u003c/p\u003e\n\n------------\n\n##### 🎉 Enter **CF-Badger** !!\n\nCF-Badger will present you with a brief form (which, by the way, is hosted on [Cloudflare Pages](https://pages.cloudflare.com)) whose final output is a short url to your desired status badge, updated every 5 minutes. \n\nEach input control of this form is eventually filled with the available options, so you won't need to guess what goes where. \n\n\n\n\u003cp align=\"center\"\u003e\n\n\n\u003cimg src=\"docs/images/sshot.png\"\u003e\n\n\u003c/p\u003e\n\n--------------\n\n### 🎯 How?\n\nWe request the outcome of your workflows directly to Github's API, on your behalf. To do this, [CF-Badger's Github App](https://github.com/apps/cf-badger) needs to be enabled on a per-repo basis, which in turn will give us read-only access to your workflow results. \n\n\n\nThis result is formatted in compliance to Shields.io schema, and provided as parameter to [Shields.io endpoint API](https://shields.io/endpoint), (🙌 without which CF-Badger wouldn't work). \n\nFinally, we'll generate and provide you with a shortened URL to the computed status badge\n\n\u003cp align=\"center\"\u003e\n\n\n\u003cimg src=\"docs/images/markdown.png\"\u003e\n\n\u003c/p\u003e\n\n## **🔐 Security Concerns**\n\nCF-Badger was inspired on **[Atrox's Github Actions Badge](https://actions-badge.atrox.dev/)**. Although I loved it, it felt too limited to be constrained to just one workflow per repo, which you cannot pick, btw. More important, it needs you to enter a personal access token with `repo` privileges, which in turn is part of the shareable URL. That was too risky...\n\nWe shaped CF-Badger to connect to Github through a Github App, because they can request very specific and, in this case, harmless permissions. \n\nThe app requests read only access to repo actions, which is *the bare minimum needed to retrieve your workflow statuses*. We won't be able to read any other kind of restricted info, much less change anything. \n\n\n\u003cp align=\"center\"\u003e\n\n\n\u003cimg src=\"docs/images/permissions.png\"\u003e\n\n\u003c/p\u003e\n\nThe access tokens used by the app has a short lived lifetime and revoking the app's permission would effectively cut us out when it does. The temporary token we use is stored internally on the persistent storage of a [Durable Object](https://blog.cloudflare.com/introducing-workers-durable-objects/) and it's never exposed to third parties nor used other than to query Github's API on your behalf. \n\n\n\nIf your use case for CF-Badger involves public repos, you might want to use Shields.io direcly. Just look in their [Builds Category](https://shields.io/category/build) for \"Github Workflows\" section.\n\n\n### 🤷 Why do you address yourself as \"we\" if you're the only contributor? \n\n\nIt kinda makes the project sound like a serious initiative. \n\n--------------\n## 🏆 Acknowledgements \n\n**[Cloudflare Workers](https://www.cloudflare.com/products/workers)**, along with [Workers KV](https://www.cloudflare.com/products/workers-kv/), [Cloudflare Pages](https://pages.cloudflare.com/) and [Durable Objects](https://blog.cloudflare.com/introducing-workers-durable-objects/). This is the blazing fast platform on which CF-Badger runs and replicates over 200+ locations worldwide. Did I mention CF-Badger is my project for the **[Cloudflare Developer Summer Challenge](https://challenge.developers.cloudflare.com/)**?\n\n**[Shields.io](https://shields.io)**, whose service renders actual badges and without which CF-Badger would generate broken images, which would be ironic.\n\n**[Atrox's Github Actions Badge](https://actions-badge.atrox.dev/)**, on which CF-Badger was inspired.\n\n**[Vitedge](https://vitedge.js.org)**, which is used to build the UI \n\n**[Miniflare](https://miniflare.dev/)**, whithout which developing is a less likeable experience overall\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffflabs%2Fcf-badger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fffflabs%2Fcf-badger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffflabs%2Fcf-badger/lists"}