Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSO login via cli without WebBrowser #4424

Open
mcouliba opened this issue Sep 25, 2020 · 24 comments
Open

SSO login via cli without WebBrowser #4424

mcouliba opened this issue Sep 25, 2020 · 24 comments
Labels
inquiry Issue is a question or reach for support

Comments

@mcouliba
Copy link

Hello,

I would like to using argocd cli as a Tekton Task (running argocd inside a container).
ArgoCD is using OpenShift OAuth. When logging in I got the following error message

argocd login argocd-server.argocd.svc --sso --plaintext
Opening browser for authentication
Performing authorization_code flow login: https://argocd-server-argocd.apps.cluster-afe0.afe0.example.opentlc.com/api/dex/auth?access_type=offline&client_id=argo-cd-cli&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2Fauth%2Fcallback&response_type=code&scope=openid+profile+email+groups+offline_access&state=lGaGXCEHVi
FATA[0001] exec: "xdg-open": executable file not found in $PATH 

I could install xdg-open but inside my container, I do not have any browser

Is there a way to SSO login without webrowser redirection?

Thanks

@mcouliba mcouliba added the bug Something isn't working label Sep 25, 2020
@jannfis
Copy link
Member

jannfis commented Sep 25, 2020

I'm afraid the OAuth with ArgoCD is only possible using a browser. However, you can create a local (technical) user and use it for automation purposes. Be sure to configure appropriate RBAC rules in Argo CD for the user, so that the user will be authorized to do what you need it to do.

@jannfis jannfis added inquiry Issue is a question or reach for support and removed bug Something isn't working labels Sep 25, 2020
@mcouliba
Copy link
Author

Thanks @jannfis.
I will do that

@seanwalker909
Copy link

Bumping this post to see if there are any plans of adding SSO login support via the REST API

@ramanNarasimhan77
Copy link

ramanNarasimhan77 commented Apr 29, 2021

My team also is facing this issue and we are using this workaround

We use keycloak for SSO and it is possible to directly obtain a TOKEN from Keycloak using REST API

export ACCESS_TOKEN=$(curl -s -X POST -H 'Accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' -d "username=${USER}" -d "password=${PASSWORD}" -d 'grant_type=password' -d "client_id=${ARGOCD_CLIENT}" -d 'scope=offline_access' -d "client_secret=${CLIENT_SECRET}" ${KEYCLOAK_REALM}/protocol/openid-connect/token | jq -r .access_token)

Once we have a token, we can use it in the cli

argocd app list --auth-token $ACCESS_TOKEN --server argocd.example.com

One caveat of this approach is that ACCESS_TOKEN has to be retrieved before running each command and both TOKEN and SERVER flags have to be passed to each and every command.

@xlanor
Copy link

xlanor commented Jun 22, 2021

Has anyone figured out a way to do this for google SSO?

It seems like creating a user seems to require an admin user being enabled in the first place. we could script this via terraform, but would prefer a cleaner approach.

@kevanslumin
Copy link

I'd like to automate the argocd login with headless chrome via chromedp or puppeteer. Could you possibly add a flag like
--browser=none to just print out the SSO URL without popping up the browser?

@cpmoore
Copy link

cpmoore commented Aug 4, 2021

I had the same issue with using argocd with openshift oauth.
I was able to emulate the oauth flow in python pretty easily. It should be possible to translate this to curl.

Edit: realized i could just get the cookie from the session object

def argocd_login(host, username, password):
    # temporarily disable ssl verification warnings
    with warnings.catch_warnings():
        urllib3.disable_warnings()
        # create session to keep cookies
        session = requests.session()
        # call initial login endpoint, will redirect to openshift oauth
        response = session.get("https://" + host + "/auth/login", allow_redirects=True, verify=False)
        # parse response to get openshift host
        parsed = urlparse(response.url)
        openshift_url = parsed.scheme + '://' + parsed.netloc
        # setup oauth and idp urls
        authorize_endpoint = '/oauth/authorize?' + parsed.query
        idp_url = openshift_url + "/login/ldapidp"
        # do an initial request to idp endpoint get to the idp endpoint to get the csrf cookie
        session.get(idp_url, allow_redirects=False, verify=False, params={
            'then': authorize_endpoint
        })
        # post csrf,username, and password to idp endpoint
        session.post(idp_url, data={
            'username': username,
            'password': password,
            'csrf': session.cookies['csrf'],
            'then': authorize_endpoint
        }, allow_redirects=True, verify=False)
        # return arocd.token from cookies
        return session.cookies['argocd.token']

@warroyo
Copy link

warroyo commented Dec 9, 2021

@jannfis can this be reopened? for some users creating a local account is not acceptable for the company's auth policies. we need a way to login without a browser using . Dex supports the resource owner password credentials grant type which should support this.

dexidp/dex#1621

@Mohjive
Copy link

Mohjive commented Dec 29, 2021

The PKCE flow should be possible to support as well.

@tarfeef101
Copy link

Commenting to indicate my support for:

  • printing the browser URL (best option)
  • something i've seen before in other apps, the ability to spin up a local server on a given port and simply wait for the user to visit it. in at least some cases, you can set the container and/or VM to forward that port back to your host machine and complete the auth flow that way

@agurgel-te
Copy link

I'm having this issue on WSL, but it's because of skratchdot/open-golang#29.

@Tronix117
Copy link

Same here, it should be possible to disable the web-browser opening and just show the URL, or just display a warning instead. It would be great to not be blocking.
On tools using xdg-open, there is usualy the possibility to disable it.

On my hand, I'm using the cli on a remote session, and there is no desktop environment.

@cslovell
Copy link

cslovell commented Oct 25, 2022

For what it's worth, if you have kubectl access, if you ensure you're using the kube context where you have argocd installed, you can set your namespace to the argocd namespace (i.e., kubectl config set-context --current --namespace=argocd) and login without a browser using the command below:

argocd login argocd.example.com --core

Here's the documentation on this. I realize this isn't SSO, but if you use SSO to handle cluster access, then it may meet the criteria.

@antoniordz96
Copy link

Can this be reopened? We are using devspaces which are like gitpods and the docker argocd container doesn't support opening a web browser. I'm happy to help implement something similar as suggested in #4424 (comment) where it just prints the link to generate a token. Similar to what the Openshift CLI does.

@blairdrummond
Copy link

FYI I have done this with AzureAD, and if you use Dex then this recent feature will allow you to solve this via federation. (That feature might not be cut into a release yet, but you can find the edge images published which work).

This effectively makes this possible with any OIDC provider via Dex. The flow is, take your github-action/gitlab-ci job/kubernetes service account token, yada yada, configure the OIDC backend for that as a connector for Dex, and do a token exchange to get a dex token. You can then pass that token with the argocd cli. I even have the ArgoCD terraform provider working with OIDC.

@achdmbp
Copy link

achdmbp commented Nov 1, 2023

in the case of running argocd cli in a remote container (such as in devspaces / gitpods). if argocd cli expose a flag to override redirect_uri, this should work, since one can configure a redirect_uri to point to an ingress/route that points to server argocd cli spins up locally in the container

@crenshaw-dev crenshaw-dev reopened this Nov 1, 2023
@achdmbp
Copy link

achdmbp commented Jan 3, 2024

in the case of running argocd cli in a remote container (such as in devspaces / gitpods). if argocd cli expose a flag to override redirect_uri, this should work, since one can configure a redirect_uri to point to an ingress/route that points to server argocd cli spins up locally in the container

just an update, this solution won't work. we cannot use arbitrary redirect url. the redirect url has to be registered in oauth.

is there a proposed solution at this point that is ready to be implemented? I'd be happy to help implement it.

@ArieLevs
Copy link

I even have the ArgoCD terraform provider working with OIDC.

Hi @blairdrummond, could you please elaborate on the token exchange you did with Terraform?
i'm trying to implement a token exchange for the argocd terraform provider, using Okta SSO, but the process seems to be not that documented except for github use case.

Thanks

@blairdrummond
Copy link

blairdrummond commented Feb 18, 2024

@ArieLevs you can't exactly do this with just Okta, instead what you do is:

  1. Set up ArgoCD to use the built-in Dex. You need to use the most recent dex image because token exchange was just released 3 weeks ago.
  2. In the dex.config, hook up Okta to dex (looks like you need either a SAML or oidc connector)?
  3. IN ADDITION to Okta, hook up github-actions to dex. Sample config below.
issuer: https://argocd.example.com/api/dex
expiry:
  idTokens: 8h
  signingKeys: 24h

staticClients:

  # Note: I think I maybe had a second client running actually which was a public client.
  # Take a look at the public client below
  - id: argocd
    name: ArgoCD
    redirectURIs:
      - https://argocd.example.com/api/dex/callback
      # Kubelogin uses these
      - http://localhost:8000
      - http://localhost:18000
    secretEnv: ARGOCD_CLIENT_SECRET
    
  # Note: anyone can use this! Beware!
  - id: public-client
    name: GHA Client
    public: true

connectors:
  # This is my Github auth config, but switch this out for SAML or OIDC for Okta
  - config:
      clientID: $GITHUB_CLIENT_ID
      clientSecret: $GITHUB_CLIENT_SECRET
      loadAllGroups: true
      orgs:
        - name: liatrio
      redirectURI: https://argocd.example.com/api/dex/callback
    id: github
    name: GitHub
    type: github

  - config:
      issuer: https://token.actions.githubusercontent.com
      scopes:
        - openid
        - groups
      userNameKey: sub
    id: github-actions
    name: github-actions
    type: oidc

oauth2:
  skipApprovalScreen: true

storage:
  config:
    inCluster: true
  type: kubernetes
telemetry:
  http: 0.0.0.0:5558
web:
  http: 0.0.0.0:5556

Users will see a screen like below, and your github actions will need a token to auth that doesn't involve Okta at all

Screen Shot 2024-02-18 at 11 30 36 AM

You can find sample code for the token exchange from a github action here. I am trying to get a PR going for Kubelogin so that kubelogin can do this instead of curl. Once you have that token, you can fire that off to ArgoCD as a bearer token and it'll work. Sample TF below

terraform {
  required_providers {
    argocd = {
      source = "oboukili/argocd"
      version = "6.0.3"
    }
  }
}

# I used this with interactive auth-code login locally,
# but switch it out with curl, OR just use a TF_VAR
data "external" "token" {
  program = [
    "sh", "-c", <<-HEREDOC
    kubelogin \
      get-token \
      --oidc-issuer-url ${var.sso_issuer} \
      --oidc-client-id ${var.client_id} \
      --grant-type authcode \
      --oidc-extra-scope openid | jq '{"token": .status.token}'
HEREDOC
  ]
}

provider "argocd" {
  auth_token  = data.external.token.result.token
  server_addr = var.argocd_host
}

Why Dex?

Dex happens to now support token-exchange, last I checked Okta does not support that yet (PingFederate does. If you use Ping you can do all this natively there and skip Dex). Once/if Okta natively supports token exchange, basically you just register Github Actions to be able to auth to Okta to get an Okta token, then fire that to your service.

IMPORTANT NOTE: Github-Actions security

The github-actions OIDC issuer there is github.com wide. Literally anyone could use that. I have a personal fork of Dex were I added lua support to do some extra authz there, I think something like rego or CEL would be better. You might just need to vet the security there to make sure that this system doesn't open up unintended access. Keeping your dex/argocd service in a private network will obviously help here

@blairdrummond
Copy link

@achdmbp you can definitely use device-code login to access argocd if you use an extra tool like kubelogin. You do a device-code login there, get the token, then plug it into whatever system.

@haiwu
Copy link

haiwu commented Feb 23, 2024

@blairdrummond : per this okta doc https://developer.okta.com/docs/guides/set-up-token-exchange/main/, does it mean that okta does support token-exchange?

@blairdrummond
Copy link

Oh snap @haiwu yes it does! Looks like you can use that for token-exchange.

In that case, you can hook ArgoCD -> Okta, then Okta humans use sso as normal, and you use that flow to get machine identities to get an Okta ID token, then send that token to ArgoCD

@haiwu
Copy link

haiwu commented Feb 23, 2024

@blairdrummond : Would this work if ArgoCD using SAML from Okta?

@alexjball
Copy link

For sessions over ssh or codespaces, where you can forward your terminal's port to your local host, you can stub out xdg-open on the remote side to avoid the error. You can then open the link in your local browser to finish the flow.

echo "#!/bin/sh" > ~/.local/bin/xdg-open
chmod +x ~/.local/bin/xdg-open

argocd login ... --sso

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
inquiry Issue is a question or reach for support
Projects
None yet
Development

No branches or pull requests