Open ExalDraen opened 5 years ago
Just wanted to say, thanks for the detailed bug description and links to all the resources.
I agree we should do something to ensure Argo CD works behind Google Cloud IAP. I think if it works for a browser, it should be solvable through CLI. I think the issue is that CLI has no concept of Google IAP's cookie and would not know to store it in local disk, let alone supply it with every CLI request.
A generic solution might be to honor any set cookie directive, and store it in a section in the ~/.argocd/config, tied to the server address. grpc-web would still need to be used, but the cookie would have to be supplied with all requests.
Thanks for the feedback @jessesuen. I agree with your analysis - the CLI has no concept of the token needed to access the resource hence the requests fail.
I'm not sure what the request/response flow looks like (i.e. what headers are set at what point), but I don't think just Set-Cookie
is enough - if I understand the docs correctly, the flow would have to be something like this:
argocd login
.refresh token
refresh token
and the client secret to generate a (1-hour) id_token
The tricky part is that most (all?) of these pieces of information need to be persisted somewhere - not sure if ~/.argocd/config
is the right place.
This SO answer has some python code that sketches out how to do it, might be a useful starting point.
@jessesuen one for community contribution?
We also use IAP and prefer to enable by default on anything private to avoid having to IP lock things. But IP locks are much easier to use with CLI tools.
I notice argocd login
has a --header
option, so in theory assuming someone could work out the required gcloud
or series of curl
commands to generate an appropriate token, would it be possible to do?:
export IAP_TOKEN="$(<insert some shell foo>)"
argocd login argocd.example.com:443 --header "'Authorization: Bearer $IAP_TOKEN"
Having had a little look through this: https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_desktop_app
I've done similar with a service account from some python app (based on this ), but never actually as a user account.
There is another aspect to it: ArgoCD behind IAP should get user identity from headers injected by IAP. Details can be found in https://cloud.google.com/iap/docs/identity-howto
I have this working using Dex AuthProxy but it's a bit of a hack. The problem I have yet to solve is how to use a GCP Service Account identity to call the ArgoCD API, either via the IAP exposed endpoint or directly backend-to-backend from StackStorm to ArgoCD API in the same cluster
dex.config: |
connectors:
- type: authproxy
id: iap_proxy
name: "Google IAP Proxy"
config:
userHeader: "X-Goog-Authenticated-User-Email"
extraArgs: # Disable HTTPS as the LBA terminates it
- --insecure
- --rootpath=/argocd
This is promising -- do you know how to add an account to argo using a user's email address? It's not possible via the argocd-cm
configmap because the account.email
key will be invalid (@
isn't allowed). It looks like argo cd itself doesn't support adding accounts locally: https://github.com/argoproj/argo-cd/issues/4967
Aside: I wonder how difficult it would be to hijack argo's native support for JWTs (on the API endpoint) to understand the JWT headers Google sends.
In our case we don't add the accounts, it seems to work by IAP and DeX magic.
IAP also does not supply us with groups.
On Tue, May 24, 2022, 5:56 PM David Kirchner @.***> wrote:
This is promising -- do you know how to add an account to argo using a user's email address? It's not possible via the argocd-cm configmap because the account.email key will be invalid (@ isn't allowed). It looks like argo cd itself doesn't support adding accounts locally: #4967 https://github.com/argoproj/argo-cd/issues/4967
Aside: I wonder how difficult it would be to hijack argo's native support for JWTs (on the API endpoint) to understand the JWT headers Google sends.
— Reply to this email directly, view it on GitHub https://github.com/argoproj/argo-cd/issues/2224#issuecomment-1136509920, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABPWAWVTQ5DVOZ4D2X547BDVLVNBLANCNFSM4IQ6MXCA . You are receiving this because you commented.Message ID: @.***>
We also use IAP and prefer to enable by default on anything private to avoid having to IP lock things. But IP locks are much easier to use with CLI tools.
I notice
argocd login
has a--header
option, so in theory assuming someone could work out the requiredgcloud
or series ofcurl
commands to generate an appropriate token, would it be possible to do?:export IAP_TOKEN="$(<insert some shell foo>)" argocd login argocd.example.com:443 --header "'Authorization: Bearer $IAP_TOKEN"
https://serverfault.com/a/1090492
probably best to use Proxy-Authorization
header in case argocd cli itself uses Authorization
has anybody got --header
working with IAP?
I tried
$ IAP_TOKEN=$(gcloud auth print-access-token)
$ argocd login my.server.url --header "Proxy-Authorization: Bearer ${IAP_TOKEN}" --sso
and also with --header "X-Goog-User-Project: my-project-name"
but no luck
Anyone managed to get this working?
For anyone still trying to solve this, I was able to get this working -- thanks to clues on this page and the google doc linked to above.
I needed to go through the several-step process (like described in the doc) to get the code
and turn that into an id_token
. That id token format is not the same as the access token you get from gcloud auth print-access-token
.
That process requires running a local server to accept the callback as part of the process, which means you have to add that uri to your allowed redirect links. (That part is not explicitly called out in the docs!)
The missing piece for me was the additional requirement to specify --grpc-web
(though I use other grpc services via HTTP2 through iap without issue 🤷). I also had to pass in the --sso
parameter. You can do this in the login
command:
argocd login myargo.server.com --header "Proxy-Authorization: Bearer ${IAP_TOKEN}" --grpc-web --sso
The --grpc-web
option gets stored in the argocd config after login, but the headers are not similarly captured in the configuration file/server section, so you have to pass them in with every command.
argocd app list YOUR_SERVER_HERE --header "Proxy-Authorization: Bearer ${IAP_TOKEN}"
I wrote up a way to manage getting & refreshing this token from bash in a gist that also has a wrapper to argocd
that hides much of this chicanery from a developer's experience.
@SeaJaredCode fyi, you can make it headless like so:
→ export ARGO_IAP_TOKEN=$(gcloud auth print-identity-token --impersonate-service-account <some-service-account> --audiences ${CLIENT_ID} --include-email)
This assumes there's a service account and everyone who needs access has serviceAccountUser
permission on that service account.
Cheers!
Summary
Make it possible to host ArgoCD on GKE behind Google cloud identity access proxy (IAP).
Problem statement
Google Cloud IAP is an OAuth2 based proxy that Google cloud users can enable to secure their HTTPS resources. If enabled, it enforces an OAuth 2.0 Google Account sign-in flow that stores a token in a browser cookie for future sign-in.
Currently (ArgoCD 1.2.0-rc2), if IAP is enabled for an ArgoCD setup running on GKE, it works just fine for the Argo web UI - including OAuth2 redirection, etc.
However, access from the
argocd
CLI to the server is not possible to the best of my knowledge - at least not when using the--grpc-web
proxy option.I believe this is because the
argocd
CLI does not cope with the OAuth2 flow and thus cannot get past Google Cloud IAP.Desired solution
A way to configure
argocd
to deal with the Google IAP auth flow so that theargocd
CLI can be used to access ArgoCD deployments protected by Google IAP.I do not know if it makes sense, but ideally the solution would be flexible and allow other OAuth2 flows.
Further information
Details of Google cloud access proxy can be found in the docs. Specifically, the section on programmatic access looks relevant: https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_desktop_app
Note: This was previously mentioned on Slack where it was suggested that an issue should be created.
Contributing
I would consider contributing myself but I am not sure what design would be preferable so I think this needs to be discussed first.