jfrog / jfrog-azure-devops-extension

Apache License 2.0
46 stars 61 forks source link

OIDC Support for Service-Connections #494

Open HenrikStanley opened 2 months ago

HenrikStanley commented 2 months ago

Is your feature request related to a problem? Please describe.

Support for Open ID Connect (OIDC) was recently added to the JFrog Platform. Currently the documentation only shows official support for GitHub https://jfrog.com/help/r/jfrog-platform-administration-documentation/openid-connect-integration

However, there is also a generic OIDC provider which can be pointed at any valid idToken provider endpoint. Microsoft recently added support for OIDC in Azure DevOps through Federated Workload Identities.

I would like for the JFrog Azure DevOps Extension to be updated so it supports Service Connections that can use the OIDC Provider flow inside JFrog for secure authentication in our CI/CD.

Describe the solution you'd like to see

To implement this, two things would be required.

  1. An update to the vss-extension.json file to add Service Connections that takes the information about the OIDC role configured in JFrog.
  2. Additions to the Authentication flow of the typescript code to support the idToken based flow.

When Microsoft announced their support for OIDC, calling it workload identity federation, they did a small mention about support for 3rd party plugins.

Following up on the documentation, we can see Microsoft has created a new API endpoint for generating an idToken from the Azure DevOps provider.

This endpoint produces a token with the following information.

{
  "jti": "<guid>",
  "sub": "sc://<DevopsOrgName>/<ProjectName>/<ServiceConnectionName>",
  "aud": "api://AzureADTokenExchange",
  "iss": "https://vstoken.dev.azure.com/<GUID>",
  "nbf": 1708639268,
  "exp": 1708640467,
  "iat": 1708639868
}

We can call the Azure DevOps API using the OAuth system access token which the Agent gets at startup and the various system variables provided by the agent.

David Corrigan is working on solving the same type of challenge for the AWS Toolkit extension for ADO adding OIDC support. While there are more boiler plate code and helper functions involved, getting the idToken from the Azure DevOps provider boils down to something like this.

const jobId = getVariableRequired("System.JobId");
const planId = getVariableRequired("System.PlanId");
const projectId = getVariableRequired("System.TeamProjectId");
const hub = getVariableRequired("System.HostType");
const uri = getVariableRequired("System.CollectionUri");
const token = getVariableRequired("System.AccessToken");

const auth = azdev.getBasicHandler('', token);
const connection = new azdev.WebApi(uri, auth);
const api = await connection.getTaskApi();
const response = await api.createOidcToken({}, projectId, hub, planId, jobId, endpointName);
const oidcToken = response.oidcToken || '';
const oidcTokenParts = oidcToken.split('.');
        if (oidcTokenParts.length !== 3) {
            throw new Error('Invalid oidc token');
        }
const oidcClaims = JSON.parse(Buffer.from(oidcTokenParts[1], 'base64').toString());

Example above is from Davids Work In Progress branch for this implementation.

Laurens Knoll has done a similar thing for the Google SDK using OIDC. https://xebia.com/blog/how-to-configure-google-cloud-workload-identity-federation-for-azure-devops/

https://github.com/binxio/azure-devops-extensions/tree/master/google/google-cloud-auth/tasks/gcp-wif-auth

Describe alternatives you've considered If applicable, a clear and concise description of any alternative solutions or features you've considered.

There are no great alternatives other than writing our own plugin, but this would break the usage of the JFrog Azure DevOps extension as the tasks depends on a valid type of Service Connection.

Additional context Add any other context or screenshots about the feature request here.

davidcorrigan714 commented 2 months ago

Glad someone besides me started this ticket 🤣, they may be tired of my OIDC requests on all the Terraform integrations. This one is next on my list. Got it working with the JFrog Generic Artifacts task so I'll clean it up in next day or so and put up the PR. See if JFrog or AWS gets it reviewed quicker, I'd bet JFrog does.