{"id":49137738,"url":"https://github.com/jantari/rewinged","last_synced_at":"2026-04-21T23:00:34.366Z","repository":{"id":59414046,"uuid":"493026623","full_name":"jantari/rewinged","owner":"jantari","description":"rewinged is a self-hosted winget package source","archived":false,"fork":false,"pushed_at":"2025-07-18T21:43:05.000Z","size":193,"stargazers_count":62,"open_issues_count":2,"forks_count":6,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-19T02:18:48.761Z","etag":null,"topics":["docker-image","golang","hacktoberfest","package-manager","self-hosted","winget"],"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/jantari.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2022-05-16T23:12:17.000Z","updated_at":"2025-07-17T16:05:11.000Z","dependencies_parsed_at":"2025-04-22T22:26:22.964Z","dependency_job_id":"b1995d42-331d-4971-b7fe-8bb8f84e6642","html_url":"https://github.com/jantari/rewinged","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/jantari/rewinged","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jantari%2Frewinged","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jantari%2Frewinged/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jantari%2Frewinged/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jantari%2Frewinged/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jantari","download_url":"https://codeload.github.com/jantari/rewinged/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jantari%2Frewinged/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32113748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T11:25:29.218Z","status":"ssl_error","status_checked_at":"2026-04-21T11:25:28.499Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["docker-image","golang","hacktoberfest","package-manager","self-hosted","winget"],"created_at":"2026-04-21T23:00:24.333Z","updated_at":"2026-04-21T23:00:34.343Z","avatar_url":"https://github.com/jantari.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rewinged\n\nrewinged is a self-hosted winget package source. It's portable and can run on Linux, Windows, in Docker, locally and in any cloud.\nrewinged reads your package manifests from a directory and makes them searchable and accessable to winget via a REST API.\n\nIt is currently in [pre-1.0](https://semver.org/#spec-item-4) development so configuration options, output and behavior may change at any time!\n\n## 🚀 Features\n\n- Directly serve [unmodified winget package manifests](https://github.com/microsoft/winget-pkgs/tree/master/manifests)\n- Add your own manifests for internal or customized software\n- Search, list, show and install software - the core winget features\n- Automatically internalize package installers to serve them to machines without internet\n- Restrict access to the package source with Entra ID authentication\n- Package manifest versions from 1.1.0 to 1.10.0 are all supported simultaneously\n- Runs on Windows, Linux and in Docker\n\n## 🚧 Not Yet Working or Complete\n\n- Correlation of installed programs and programs in the repository is not perfect (in part due to [this](https://github.com/microsoft/winget-cli-restsource/issues/59) and [this](https://github.com/microsoft/winget-cli-restsource/issues/166))\n- Live reload of manifests (works for new and changed manifests, but removals are only picked up on restart)\n- Probably other stuff? It's work-in-progress - please submit an issue and/or PR if you notice anything!\n\n## 🧭 Getting Started\n\n### 💾 Binaries\n\nDownload the latest [release](https://github.com/jantari/rewinged/releases), extract and run it!\n\n### 🐋 Docker\n\n```\ndocker run \\\n  -e REWINGED_LISTEN='0.0.0.0:8080' \\\n  -p 8080:8080 \\\n  -v ${PWD}/packages:/packages:ro \\\n  ghcr.io/jantari/rewinged:stable\n```\n\n### ⚙️ Configuration\n\nrewinged can be configured through commandline arguments, environment variables and a JSON configuration file.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCommandline Arguments\u003c/b\u003e\u003c/summary\u003e\n\nCommandline arguments have the highest priority and take precedence over both environment variables and the configuration file.\n\n```\n  -autoInternalize\n        Turn on the auto-internalization feature\n  -autoInternalizePath string\n        The directory where auto-internalized installers will be stored (default \"./installers\")\n  -autoInternalizeSkip string\n        List of hostnames excluded from auto-internalization (comma or space to separate)\n  -configFile string\n        Path to a json configuration file (optional)\n  -https\n        Serve encrypted HTTPS traffic directly from rewinged without the need for a proxy\n  -httpsCertificateFile string\n        The webserver certificate to use if HTTPS is enabled (default \"./cert.pem\")\n  -httpsPrivateKeyFile string\n        The private key file to use if HTTPS is enabled (default \"./private.key\")\n  -listen string\n        The address and port for the REST API to listen on (default \"localhost:8080\")\n  -logLevel string\n        Set log verbosity: disable, error, warn, info, debug or trace (default \"info\")\n  -manifestPath string\n        The directory to search for package manifest files (default \"./packages\")\n  -sourceAuthEntraIDAuthorityURL string\n        Authority/Issuer URL of the EntraID App used for authenticating clients\n  -sourceAuthEntraIDResource string\n        ApplicationID of the EntraID App used for authenticating clients\n  -sourceAuthType string\n        Require authentication to interact with the REST API: none, microsoftEntraId (default \"none\")\n  -trustedProxies string\n        List of IPs from which to trust Client-IP headers (comma or space to separate)\n  -version\n        Print the version information and exit\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eEnvironment Variables\u003c/b\u003e\u003c/summary\u003e\n\nEnvironment variables take precedence over the configuration file, but are overridden by any commandline arguments if passed.\n\n```\nREWINGED_CONFIGFILE (string)\nREWINGED_AUTOINTERNALIZE (bool)\nREWINGED_AUTOINTERNALIZEPATH (string)\nREWINGED_AUTOINTERNALIZESKIP (string)\nREWINGED_HTTPS (bool)\nREWINGED_HTTPSCERTIFICATEFILE (string)\nREWINGED_HTTPSPRIVATEKEYFILE (string)\nREWINGED_LISTEN (string)\nREWINGED_LOGLEVEL (string)\nREWINGED_MANIFESTPATH (string)\nREWINGED_SOURCEAUTHENTRAIDAUTHORITYURL (string)\nREWINGED_SOURCEAUTHENTRAIDRESOURCE (string)\nREWINGED_SOURCEAUTHTYPE (string)\nREWINGED_TRUSTEDPROXIES (string)\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eConfiguration File\u003c/b\u003e\u003c/summary\u003e\n\nUse the `-configFile` argument or `REWINGED_CONFIGFILE` environment variable to enable the config file option.\nrewinged will not look for any configuration file by default. Config file must be valid JSON.\n\n```json\n{\n  \"autoInternalize\": false,\n  \"autoInternalizePath\": \"./installers\",\n  \"autoInternalizeSkip\": \"\",\n  \"https\": false,\n  \"httpsCertificateFile\": \"./cert.pem\",\n  \"httpsPrivateKeyFile\": \"./private.key\",\n  \"listen\": \"localhost:8080\",\n  \"logLevel\": \"info\",\n  \"manifestPath\": \"./packages\",\n  \"sourceAuthEntraIDAuthorityURL\": \"\",\n  \"sourceAuthEntraIDResource\": \"\",\n  \"sourceAuthType\": \"none\",\n  \"trustedProxies\": \"\"\n}\n```\n\n\u003c/details\u003e\n\n### 🪄 Using rewinged\n\nYou can run rewinged and test the API by opening `http://localhost:8080/api/information`\nor `http://localhost:8080/api/packages` in a browser or with `curl` / `Invoke-RestMethod`.\n\nBut to use it with winget you will have to set up HTTPS because winget **requires**\nREST-sources to use HTTPS - plaintext HTTP is not allowed. If you do not have an internal\nPKI or a certificate from a publicly trusted CA like Let's Encrypt you can use then you\ncan generate and trust a new self-signed certificate for testing purposes:\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eGenerate and trust a certificate and private key in PowerShell 5.1\u003c/b\u003e\u003c/summary\u003e\n\n```powershell\n# Because we are adding a certificate to the local machine store, this has to be run in an elevated PowerShell session\n\n$IPs = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |\n    Foreach-Object GetIPProperties |\n    Foreach-Object UnicastAddresses |\n    Foreach-Object Address |\n    Foreach-Object {\n        \"\u0026IPAddress=$( [System.Net.IPAddress]::new($_.GetAddressBytes() ))\"\n    }\n\n[string]$SanIPs = -join $IPs\n\n$SelfSignedCertificateParameters = @{\n    'Subject'         = 'localhost'\n    'TextExtension'   = @(\"2.5.29.17={text}DNS=localhost${SanIPs}\")\n    'NotAfter'        = (Get-Date).AddYears(1)\n    'FriendlyName'    = 'rewinged HTTPS'\n    'KeyAlgorithm'    = 'RSA'\n    'KeyExportPolicy' = 'Exportable'\n}\n$cert = New-SelfSignedCertificate @SelfSignedCertificateParameters\n\n$RSAPrivateKey    = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)\n$PrivateKeyBytes  = $RSAPrivateKey.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)\n$PrivateKeyBase64 = [System.Convert]::ToBase64String($PrivateKeyBytes, [System.Base64FormattingOptions]::InsertLineBreaks)\n\n$CertificateBase64 = [System.Convert]::ToBase64String($cert.Export('Cert'), [System.Base64FormattingOptions]::InsertLineBreaks)\n\nSet-Content -Path private.key -Encoding Ascii -Value @\"\n-----BEGIN RSA PRIVATE KEY-----`r`n${PrivateKeyBase64}`r`n-----END RSA PRIVATE KEY-----\n\"@\n\nSet-Content -Path cert.pem -Encoding Ascii -Value @\"\n-----BEGIN CERTIFICATE-----`r`n${CertificateBase64}`r`n-----END CERTIFICATE-----\n\"@\n\n$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('Root', 'LocalMachine')\n$store.Open('ReadWrite')\n$store.Add($cert)\n$store.Close()\n\nRemove-Item $cert.PSPath\n```\n\u003c/details\u003e\n\nThen, run rewinged with HTTPS enabled:\n\n```\n./rewinged -https -listen localhost:8443\n```\n\nadd it as a package source in winget:\n\n```\nwinget source add -n rewinged-local -a https://localhost:8443/api -t \"Microsoft.Rest\"\n```\n\nand query it!\n\n```\n~\n❯ winget search -s rewinged-local -q bottom\nName   Id              Version\n------------------------------\nbottom rewinged.bottom 0.6.8\n\n~\n❯ winget install -s rewinged-local -q bottom\nFound bottom [rewinged.bottom] Version 0.6.8\nThis application is licensed to you by its owner.\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\nDownloading https://github.com/ClementTsang/bottom/releases/download/0.6.8/bottom_x86_64_installer.msi\n  ██████████████████████████████  1.56 MB / 1.56 MB\nSuccessfully verified installer hash\nStarting package install...\nSuccessfully installed\n\n~ took 8s\n❯\n```\n\n## 🤖 Auto-Internalization\n\nWith auto-internalization enabled, rewinged will automatically:\n\n1. Download all installers referenced in your package manifests (InstallerUrl fields)\n2. Serve all of the downloaded installer files itself, locally, on the `/installers/` URL-path\n3. Dynamically rewrite all InstallerUrls returned from its APIs to point to itself instead of the original source\n\nYou can choose a path where rewinged will store the downloaded installers with `autoInternalizePath`\nand you can exempt a list of hostnames from being auto-internalized with `autoInternalizeSkip`.\nThis is useful if you have custom manifests that already point to internal sources and there is no\nneed to re-internalize them again, or when certain installers are very large and you just don't want\nto store them locally. For example:\n\n```\n./rewinged -autoInternalize -autoInternalizeSkip \"internal.example.org github.com\"\n```\n\n## 🔒 Entra ID Authentication\n\nYou can optionally enable Entra ID authentication for rewinged. This means only authorized users will be able to\nget software from the repository. Currently, this is an all-or-nothing setting meaning the entire source repository\nand all packages will require authentication to access, and you cannot restrict individual packages to specific\ngroups of users yet. If a user is able to successfully authenticate with your Entra ID tenant they will be able\nto access everything in the repository. If they fail to authenticate, for example because you have not assigned the\nuser aceess to rewinged or because of Conditional Access policies, they will not be able to access anything.\n\nOn a hybrid- or cloud-only Entra ID-joined Windows device, the users authentication through winget to rewinged\nshould be transparent and automatic (SSO). Otherwise the user will see authentication windows.\n\nTo configure Entra ID Authentication, an application must be registered in your Entra ID tenant.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eRegister an application for use with winget REST source authentication in Entra ID\u003c/b\u003e\u003c/summary\u003e\n\nThe following is based on Microsofts [`New-MicrosoftEntraIdApp.ps1`](https://github.com/microsoft/winget-cli-restsource/blob/main/Tools/PowershellModule/src/Library/New-MicrosoftEntraIdApp.ps1) script.\n\n```powershell\n$ScopeId = [Guid]::NewGuid().ToString()\n$app = New-AzADApplication -DisplayName \"rewinged\" -SignInAudience AzureADMyOrg -RequestedAccessTokenVersion 2 -Api @{\n    oauth2PermissionScopes = @(\n        @{\n            adminConsentDescription = \"Sign in to access rewinged REST source\"\n            adminConsentDisplayName = \"Access rewinged REST source\"\n            userConsentDescription  = \"Sign in to access rewinged REST source\"\n            userConsentDisplayName  = \"Access rewinged REST source\"\n            id = $ScopeId\n            isEnabled = $true\n            type = \"User\"\n            value = \"user_impersonation\"\n        }\n    )\n    preAuthorizedApplications = @(\n        @{\n            # \"App Installer\"\n            appId = \"7b8ea11a-7f45-4b3a-ab51-794d5863af15\"\n            delegatedPermissionIds = @($ScopeId)\n        },\n        @{\n            # \"Microsoft Azure CLI\"\n            appId = \"04b07795-8ddb-461a-bbee-02f9e1bf7b46\"\n            delegatedPermissionIds = @($ScopeId)\n        },\n        @{\n            # \"Microsoft Azure PowerShell\"\n            appId = \"1950a258-227b-4e31-a9cf-717495945fc2\"\n            delegatedPermissionIds = @($ScopeId)\n        }\n    )\n}\n\nUpdate-AzADApplication -ApplicationId $app.AppId -IdentifierUri \"api://$($app.AppId)\"\n\nWrite-Output \"Done. Application Id: $($app.AppId)\"\n```\n\u003c/details\u003e\n\nThen start rewinged with the authentication-related configuration set:\n\n```\n./rewinged -https -sourceAuthType microsoftEntraId -sourceAuthEntraIDAuthorityURL \"https://login.microsoftonline.com/\u003cYour-Tenant-Id\u003e/v2.0\" -sourceAuthEntraIDResource \"\u003cEntra-Application-Id\u003e\"\n```\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e⚠️\u003c/th\u003e\n    \u003ctd\u003eWhen you enable authentication, ensure all of your package manifests are ManifestVersion 1.10.0 or higher. Previous ManifestVersions did not fully support authentication and winget will not be able to correctly retrieve such packages when authentication is enabled.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Helpful reference documentation\n\nrewinged: Run `./rewinged -help` to see all available command-line options.\n\nwinget-cli-restsource: https://github.com/microsoft/winget-cli-restsource\n\nwinget restsource API: https://github.com/microsoft/winget-cli-restsource/blob/main/documentation/WinGet-1.1.0.yaml\n\nIf you have trouble, questions or suggestions about rewinged please open an issue!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjantari%2Frewinged","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjantari%2Frewinged","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjantari%2Frewinged/lists"}