Conversation
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds Cloudsmith as an additional OIDC-backed token provider in the Dependabot proxy’s OIDC subsystem, enabling the proxy to exchange a GitHub Actions OIDC token for a Cloudsmith API token and then use it for authenticated registry access (e.g., via existing OIDC-aware handlers like the npm registry handler).
Changes:
- Add Cloudsmith-specific OIDC parameter parsing and selection in
CreateOIDCCredential, including an audience fallback derived from a repository-owner environment variable. - Implement Cloudsmith token exchange (
GetCloudsmithAccessToken*) in the shared GitHub Actions OIDC client module. - Extend unit tests to cover Cloudsmith credential creation and token exchange behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| internal/oidc/oidc_credential.go | Adds CloudsmithOIDCParameters, credential detection, and audience defaulting via env var. |
| internal/oidc/actions_oidc.go | Implements Cloudsmith token exchange request/response handling and devops helper. |
| internal/oidc/oidc_credential_test.go | Adds Cloudsmith cases to credential creation tests and env-driven audience behavior test. |
| internal/oidc/actions_oidc_test.go | Adds Cloudsmith token exchange tests using httpmock. |
| tokenURL := fmt.Sprintf("https://%s/openid/%s/", params.ApiHost, params.OrgName) | ||
| req, err := http.NewRequestWithContext(ctx, "POST", tokenURL, bytes.NewReader(requestBodyJson)) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to create cloudsmith token request: %w", err) | ||
| } |
There was a problem hiding this comment.
The Cloudsmith URL is built via string interpolation with unescaped params.OrgName and unchecked params.ApiHost. This can produce invalid URLs for org names containing reserved characters, and api-host values like good.com@evil.com would be interpreted as userinfo+host by URL parsing. Build the request URL via url.URL{Scheme:"https", Host: ...} (validating Host has no scheme/userinfo/path) and url.PathEscape the org name.
There was a problem hiding this comment.
This seems to be an established pattern in the codespace, so for consistency I will ignore this suggestion.
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
|
Added missing oidc url authentication handling tests for the Cloudsmith provider. |
… oidc Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
brettfo
left a comment
There was a problem hiding this comment.
Thank you for the PR! Overall it looks great and exactly what I'd hope it would look like. The only feedback (specific comments at their appropriate locations) is that the environment variable GITHUB_REPOSITORY_OWNER won't be available to the proxy at runtime so you'll have to make the audience parameter required.
Once this is all done there will be some internal PRs required to update the dependabot.yml schema to allow these additional values as well as some documentation updates, but I'll take care of that when the time comes.
|
Regarding your comment about testing it locally, it's difficult. You can build this image by running |
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
|
Thank you for reviewing this. I have made the audience parameter mandatory and named it the same as in the Cloudsmith OIDC Github Action. Also, it is cool to see the Dependabot internals being open sourced. I will look into the CLI more and how to set up local testing for future contributions. |
internal/oidc/actions_oidc.go
Outdated
| return nil, fmt.Errorf("failed to read cloudsmith token response body: %w", err) | ||
| } | ||
|
|
||
| if resp.StatusCode != http.StatusOK { |
There was a problem hiding this comment.
Could you expand this check to also allow http.StatusCreated? The GitHub actions implementation accepts both 200 and 201 and .StatusCreated is what corresponds to that.
There was a problem hiding this comment.
That's a good catch, I missed that detail. I will update it.
Signed-off-by: joniumGit <52005121+joniumGit@users.noreply.github.com>
| } | ||
|
|
||
| req.Header.Set("Content-Type", "application/json") | ||
| req.Header.Set("Accept", "application/json") |
There was a problem hiding this comment.
I add an extra header here compared to the CLI, but I don't think it should cause issues. The CLI implementation assumes the response to be JSON.
| if tokenResp.Token == "" { | ||
| return nil, fmt.Errorf("cloudsmith token response does not contain a token") | ||
| } |
There was a problem hiding this comment.
The cli seems to be more defensive in this validation, should I add more?
!token || typeof token !== "string" || token.trim() === ""There was a problem hiding this comment.
The current check against an empty string should suffice. The deserialization specified in the struct ensures it's a string and if we're getting tokens with leading or trailing whitespace that seems like an issue with their endpoint.
|
I went through the implementation again side by side with the CLI and docs after your comment. I only found a couple minor details I commented on. |
|
Thank you again for all your work. If you'll give me a few days I'll see if I can get a trial Cloudsmith account set up to test against just to make sure we didn't miss anything. In the meantime I'll start talking with my team and work on the internal PRs necessary to support this. On a related note if you need to catch my attention on this and I haven't responded yet, you can email me directly at |
Implements support for OIDC authentication to the private registry service Cloudsmith
The implementation is based on the information available in the official documentation and in the vendor provided GitHub Action. The code is mostly copied from the existing JFrog OIDC implementation and adapted to work with Cloudsmith as I am not a Go developer and not that familiar with it.
Notes:
actions_oidccode.I appreciate and welcome all feedback on the PR.