googleapis / google-auth-library-python

Google Auth Python Library
https://googleapis.dev/python/google-auth/latest/
Apache License 2.0
752 stars 301 forks source link

Support POST verb for URL-sourced credentials to enable Azure Pipelines WIF #1508

Open laurensknoll opened 3 months ago

laurensknoll commented 3 months ago

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

External account URL-sourced credentials require a HTTP GET endpoint:

An HTTP GET request should be sent to this local url while injecting the headers key/values (if provided in the configuration file) in the request header. The request should respond with the external credentials subject token to be passed to STS token endpoint. Source: https://google.aip.dev/auth/4117#determining-the-subject-token-in-microsoft-azure-and-url-sourced-credentials

The Azure DevOps OIDC token endpoint, however, requires a HTTP POST request:

POST https://dev.azure.com/{organization}/{scopeIdentifier}/_apis/distributedtask/hubs/{hubName}/plans/{planId}/jobs/{jobId}/oidctoken?serviceConnectionId={serviceConnectionId}&api-version=7.1-preview.1

Source: https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/oidctoken/create?view=azure-devops-rest-7.1

Consequently, URL-sourced credentials can't yet be applied to Azure Pipelines. The process fails with the following error, when using the specified credential file:

There was a problem refreshing your current auth tokens: ('Unable to retrieve Identity Pool subject token', '{"count":1,"value":{"Message":"The requested resource does not support http method \'GET\'."}}')
{
  "type": "external_account",
  "audience":"//iam.googleapis.com/projects/.../locations/global/workloadIdentityPools/example/providers/ado",
  "subject_token_type":"urn:ietf:params:oauth:token-type:jwt",
  "token_url":"https://sts.googleapis.com/v1/token",
  "credential_source":{
    "url":"https://dev.azure.com/.../.../_apis/distributedtask/hubs/build/plans/519d9925-3aa9-481d-ac99-8d10e3f105ec/jobs/12f1170f-54f2-53f3-20dd-22fc7dff55f9/oidctoken?serviceConnectionId=563d287e-a228-4e4e-9293-bbe6adb74605",
    "headers":{
      "Authorization":"Bearer ...",
      "Accept":"application/json;api-version=7.2-preview.1"
    },
    "format":{
      "type":"json",
      "subject_token_field_name":"oidcToken"
    }
  },
  "service_account_impersonation_url":"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/ado-deployer@...iam.gserviceaccount.com:generateAccessToken"
}

Describe the solution you'd like

Ability to use POST URL-sourced credentials endpoints.

Describe alternatives you've considered

AWS credentials are supported with a dedicated credential source type. Could be an option, as it reduces the need for the Bearer <System.AccessToken>-header. See: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken

lsirac commented 3 months ago

Hi @laurensknoll, you can create your own custom credential supplier. This approach is much more flexible.

laurensknoll commented 3 months ago

Hi @lsirac , Thanks for the reference. Are the custom credential suppliers also easy to distribute? I prefer the built-in credentials as it doesn't require additional dependencies for the consumers.

btw, I've temporarily settled on the ExecutableSourceCredential to execute the post request.