OCI Authentication Hardcoded for Azure

Abierto
#1,946 3 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
42/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
csharp, powershell

Línea de trabajo

Empieza leyendo src/code/ContainerRegistryServerAPICalls.cs, especialmente GetContainerRegistryAccessToken y los helpers de solicitud de tokens, y luego reproduce el fallo de GHCR del issue. Compara el flujo existente de ACR con el ejemplo de Get-OciBearerToken enlazado en el informe. El trabajo estará terminado cuando las instalaciones OCI anónimas y autenticadas funcionen para registros compatibles sin romper la autenticación de ACR.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Needs-Triage
Prerequisites
  • Write a descriptive title.
  • Make sure you are able to repro it on the latest released version
  • Search the existing issues.
Steps to reproduce

The authentication mechanisms used on OCI/Container Registries is essentially hardcoded to only work for ACR based registries. This makes it impossible to use PSResourceGet with other OCI registries that don't follow the ACR specific auth flow.

For example it is not possible to install from GitHub's Container/OCI repository. I've got a test nupkg published at https://github.com/jborean93/PowerShell-PublishTest/pkgs/container/publishtest and this is what happens when you try to install it with and without a credential with PSResourceGet 1.2.0-rc3

Register-PSResourceRepository -Name GHCR -Uri https://ghcr.io -ApiVersion ContainerRegistry

# Try it with anonymous access/no credential
Install-PSResource -Name jborean93/publishtest -Repository GHCR -Debug -Verbose -TrustRepository
$Error[1] | Select-Object *
DEBUG: Package version parsed as NuGet version: '1.2.0-rc3'
DEBUG: Reading package metadata from: '/home/jborean/.local/share/powershell/Modules/Microsoft.PowerShell.PSResourceGet/1.2.0/PSGetModuleInfo.xml'
DEBUG: In InstallPSResource::ProcessInstallHelper()
DEBUG: In InstallHelper::BeginInstallPackages()
DEBUG: Parameters passed in >>> Name: 'jborean93/publishtest'; VersionRange: ''; NuGetVersion: ''; VersionType: 'NoVersion'; Version: ''; Prerelease: 'False'; Repository: 'GHCR'; AcceptLicense: 'False'; Quiet: 'False'; Reinstall: 'False'; TrustRepository: 'True'; NoClobber: 'False'; AsNupkg: 'False'; IncludeXml 'True'; SavePackage 'False'; TemporaryPath ''; SkipDependencyCheck: 'False'; AuthenticodeCheck: 'False'; PathsToInstallPkg: '/home/jborean/.local/share/powershell/Modules,/home/jborean/.local/share/powershell/Scripts'; Scope 'CurrentUser'
DEBUG: In InstallHelper::ProcessRepositories()
VERBOSE: Setting Secret Management network credentials
VERBOSE: Attempting to search for packages in 'GHCR'
DEBUG: In InstallHelper::InstallPackages()
DEBUG: In InstallHelper::InstallPackage()
DEBUG: In ContainerRegistryServerAPICalls::FindName()
DEBUG: In ContainerRegistryServerAPICalls::FindPackagesWithVersionHelper()
DEBUG: In ContainerRegistryServerAPICalls::GetContainerRegistryAccessToken()
DEBUG: In ContainerRegistryServerAPICalls::IsContainerRegistryUnauthenticated()
DEBUG: Is repository unauthenticated: False
DEBUG: In ContainerRegistryServerAPICalls::GetContainerRegistryRefreshToken()
DEBUG: In ContainerRegistryServerAPICalls::GetHttpResponseJObjectUsingContentHeaders()
Install-PSResource: Response returned error with status code MethodNotAllowed: Method Not Allowed.
VERBOSE: Attempting to delete '/tmp/a36c194f-1a8b-4239-8ec3-ae8c0e2f5038'
VERBOSE: Successfully deleted '/tmp/a36c194f-1a8b-4239-8ec3-ae8c0e2f5038'
Install-PSResource: Package(s) 'jborean93/publishtest' could not be installed from repository 'GHCR'.

# $Error[1]
PSMessageDetails      : 
Exception             : System.Exception: Response returned error with status code MethodNotAllowed: Method Not Allowed.
                           at Microsoft.PowerShell.PSResourceGet.ContainerRegistryServerAPICalls.SendRequestAsync(HttpRequestMessage 
                        message) in C:\__w\1\s\PSResourceGet\src\code\ContainerRegistryServerAPICalls.cs:line 1170
                           at Microsoft.PowerShell.PSResourceGet.ContainerRegistryServerAPICalls.GetHttpResponseJObjectUsingContentHead
                        ers(String url, HttpMethod method, String content, Collection`1 contentHeaders, ErrorRecord& errRecord) in 
                        C:\__w\1\s\PSResourceGet\src\code\ContainerRegistryServerAPICalls.cs:line 1045
TargetObject          : Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource
CategoryInfo          : InvalidResult: (Microsoft.PowerShel…s.InstallPSResource:InstallPSResource) [Install-PSResource], Exception
FullyQualifiedErrorId : HttpRequestCallFailure,Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1}

The same error occurs when you use a -Credential with a GitHub username/PAT. The error may vary depending on whether there is an Az context available as PSResourceGet falls back on this for all registries.

The reason is because GetContainerRegistryAccessToken is coded to do the following

  • Use a cached token from a previous request (not applicable here)
  • Retrieve the Azure AccessToken and TenantId from the SecretStore if a credential is set on the registered repository (not applicable here)
  • Checks if the registry allows unauthenticated requests (false here)
    • The logic for getting an anonymous token is also ACR specific and won't work for other OCI repositories
  • Fallback to getting the Az Access Token from DefaultAzureCredential
    • If none available it will fail here
    • In my case I do have an az token available
  • If we have an Az AccessToken from SecureStore or the environment use an ACR OAuth2 flow to get the ACR bearer token
    • This auth flow is ACR specific and fails with the error you see above
  • If not AccessToken then it fails

The 3 problems I see here

  • The anonymous token workflow needs to be updated to work generically
  • The oauth2/exchange workflow that ultimately gets the ACR bearer token from an Az AccessToken needs to be selectively done (some flag on the registered repository maybe?)
  • If a credential is passed in then the oauth2/exchange flow should not be done unless
    • The incoming credential is an Az AccessToken from something like Get-AzAccessToken
    • Not if its an Azure client id and secret as that is just used directly in the token exchange

I'm hoping to send through a PR to try and fix this at least for some of the scenarios but wanted to raise the issue to at least summarise what is happening. I've written Get-OciBearerToken to show the workflow that I've found works for ACR, MAR, GHCR, and hopefully any other OCI compliant registry. I've used this function to

  • push a new package for ACR, GHCR
    • GHCR uses the GitHub username and PAT with write:packages set or through the GHA GITHUB_TOKEN value
    • ACR can use an app client_id and secret value directly
    • ACR can use the AccessToken returned by Get-AzAccessToken for any valid connection using the oauth2/exchange to get the ACR refresh token
  • pull from ACR, MAR, GHDR
    • Using anonymous access
    • With the same credential as push

The biggest hiccup is figuring out whether we have an Az AccessToken to do the oauth2/exchange step.

Expected behavior
Module can be installed with no credential when the registry allows it or with a credential when it is private.
Actual behavior
See above (fails)
Error details
See above
Environment data
ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Binary     1.2.0      rc3        Microsoft.PowerShell.PSResourceGet  {Compress-PSResource, Find-PSResource, Get-InstalledPSResource, G…


Name                           Value
----                           -----
PSVersion                      7.5.1
PSEdition                      Core
GitCommitId                    7.5.1
OS                             Fedora Linux 43 (Server Edition)
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Visuals

No response

Lenguaje dominante
C#
Estrellas
576
Forks
114
Merge medio
1 d 2 h
PR fusionados (30 d)
7

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de PowerShell/PSResourceGet

Todos los issues de PowerShell/PSResourceGet

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.