shields
shields copied to clipboard
Sonarcloud badges do not work for private repositories
Are you experiencing an issue with...
shields.io
🐞 Description
SonarQube / SonarCloud badges for private repositories need a token, similar to CircleCI.
For Sonar badges, this token cannot be configured though, making them unusable for private repos.
It seems there is support in the code, but it uses statically configured auth: https://github.com/badges/shields/blob/b9955143dbc6f50e9389cbcaa82460a6cb1dadef/services/sonar/sonar-base.js#L53
🔗 Link to the badge
No response
💡 Possible Solution
Add a token option to the Sonar badges.
Hi. There are some services (like CircleCI) where it is possible to generate a token which only allows access to a very narrow range of summary stats and no access to write or perform actions. These are safe to expose in a badge URL.
With SonarCloud, you can configure auth credentials for self-hosted instances of shields https://github.com/badges/shields/blob/master/doc/server-secrets.md#sonarqube
I don't use sonar myself but looking over the docs, even the most restricted tokens you can generate from Sonar allow the Execute Analysis permission and possibly read access to more data than you would want to expose. I think my assessment that these tokens probably aren't safe to expose in a badge URL.
Thanks @chris48s! Yes, I know I can use a self-hosted shields instance but I'd like to avoid that.
Sonarcloud creates tokens for its own badges automatically, which are safe to expose and are intended for public access. There is no need to manually create tokens.
I cropped the actual token out of the screenshot, but it's included in the badge URL. The URL looks like this:
https://sonarcloud.io/api/project_badges/measure?project=[project-name]&metric=alert_status&token=[token]
Thanks for the info.
Shields provides quite a large number of of badges for Sonar The way our badges work is we request the metrics we want to present via the sonar API.
So if we take swellaby:letra (a public project) as an example
If we want to make the tech debt badge, we call
https://sonarcloud.io/api/measures/component?componentKey=swellaby%3Aletra&metricKeys=sqale_debt_ratio
If we want to make the test results badge, we call
https://sonarcloud.io/api/measures/component?componentKey=swellaby%3Aletra&metricKeys=tests%2Ctest_failures%2Cskipped_tests
Then for self-hosting users, if we have a token set, we pass that when we call the Sonar API. The way Sonar does this is using HTTP Basic Auth. The token is the username and the pasword is blank.
Do the badge tokens work as API keys?
By which I mean
If you take your example above and call
curl -u [token]: --include "https://sonarcloud.io/api/measures/component?componentKey=[project-name]&metricKeys=sqale_debt_ratio"
or
curl -u [token]: --include "https://sonarcloud.io/api/measures/component?componentKey=[project-name]&metricKeys=tests%2Ctest_failures%2Cskipped_tests"
(just to explain the syntax here the curl syntax for basic auth is curl -u [user]:[pass] so curl -u [token]: here uses basic auth to pass the token as the username with a blank password)
Does that work, or do you get a 401 Unauthorized?
If it works, this badge token could work in place of a Project Analysis Token.
Thank you @chris48s!
It appears they don't. I create a private test repository to demonstrate the use of these tokens. The repository is empty and will be deleted when this ticket is closed, so I'm not worried about leaking tokens. Besides, as shown below, the token has no permissions other than retrieving the badge.
SonarCloud gives me a token of af0a4f25121e2ec904ef8e205be64f8731da1053 for the project sonarcloud-badge-demo.
https://sonarcloud.io/api/project_badges/measure?project=sonarcloud-badge-demo&metric=vulnerabilities&token=af0a4f25121e2ec904ef8e205be64f8731da1053
Unfortunately it seems this token can only be used for badges and it's not a "real" API token.
curl -u "af0a4f25121e2ec904ef8e205be64f8731da1053:" --include "https://sonarcloud.io/api/measures/component?componentKey=sonarcloud-badge-demo&metricKeys=vulnerabilities"
HTTP/2 401
However, the SonarCloud badges are SVG, and the textual value can be retrieved easily.
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="127">
<!-- SONARCLOUD MEASURE -->
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="127" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<rect fill="#555" height="20" width="108"/>
<rect fill="#00aa00" height="20" width="19" x="108"/>
<rect fill="url(#b)" height="20" width="127"/>
</g>
<g fill="#fff" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11" text-anchor="left">
<text x="26" y="15" textLength="76" fill="#010101" fill-opacity=".3">vulnerabilities</text>
<text x="26" y="14" textLength="76">vulnerabilities</text>
<text x="114" y="15" textLength="7" fill="#010101" fill-opacity=".3">0</text>
<text x="114" y="14" textLength="7">0</text>
</g>
<path fill="#010101" fill-opacity=".3" d="M19.58682 9.81722A3.78893 3.78893 0 0 0 17.78048 8.603v-.04378a3.77165 3.77165 0 1 0-7.5433 0v.05069a3.77165 3.77165 0 1 0 3.78317 6.28186 3.7705 3.7705 0 0 0 5.56416-5.0688zm-2.91802 5.21164a2.8247 2.8247 0 0 1-2.8224-2.82124.47463.47463 0 0 0-.94925 0 3.7486 3.7486 0 0 0 .53223 1.9296 2.8201 2.8201 0 1 1-1.08058-4.57805h.01152a1.3202 1.3202 0 0 1 .30758.14745.4747.4747 0 0 0 .61748-.72115 2.1266 2.1266 0 0 0-.61402-.32371 3.75898 3.75898 0 0 0-1.29946-.2304h-.182a2.82125 2.82125 0 1 1 4.45478 2.4192.47462.47462 0 1 0 .55066.773 3.78317 3.78317 0 0 0 1.44806-2.0736 2.8224 2.8224 0 0 1-.97574 5.46969z"/>
<path fill="#f3702a" d="M19.58682 9.09722A3.78893 3.78893 0 0 0 17.78048 7.883v-.04378a3.77165 3.77165 0 1 0-7.5433 0v.05069a3.77165 3.77165 0 1 0 3.78317 6.28186 3.7705 3.7705 0 0 0 5.56416-5.0688zm-2.91802 5.21164a2.8247 2.8247 0 0 1-2.8224-2.82124.47463.47463 0 0 0-.94925 0 3.7486 3.7486 0 0 0 .53223 1.9296 2.8201 2.8201 0 1 1-1.08058-4.57805h.01152a1.3202 1.3202 0 0 1 .30758.14745.4747.4747 0 0 0 .61748-.72115 2.1266 2.1266 0 0 0-.61402-.32371 3.75898 3.75898 0 0 0-1.29946-.2304h-.182a2.82125 2.82125 0 1 1 4.45478 2.4192.47462.47462 0 1 0 .55066.773 3.78317 3.78317 0 0 0 1.44806-2.0736 2.8224 2.8224 0 0 1-.97574 5.46969z"/>
</svg>
So in order to make this supported on shields.io, it would have to be implemented the same way as for CircleCI, simply one more query parameter (e.g. here). And when a token is used, the service would have to parse the SVG rather than use the normal API.