department-of-veterans-affairs / va.gov-team

Public resources for building on and in support of VA.gov. Visit complete Knowledge Hub:
https://depo-platform-documentation.scrollhelp.site/index.html
280 stars 195 forks source link

Keycloak/Argo Integration #39147

Closed LindseySaari closed 2 years ago

LindseySaari commented 2 years ago

Description

Since we are using Keycloak as a SSO OIDC provider for both platform-console and Argo, we will be able to use the token returned from Keycloak to make Argo API calls from platform console

Acceptance Criteria

https://github.com/department-of-veterans-affairs/platform-console-api/pull/186

LindseySaari commented 2 years ago

Keycloak/Argo Intregration Local Setup

Keycloak Setup

Setup

Install helm via brew brew install helm Use this guide to set up keycloak via helm Note: You might have to use $ helm install keycloak codecentric/keycloak instead of $ helm install --name keycloak codecentric/keycloak

  1. Create this ingress route

  2. Run kubectl apply -f name_of_file.yml

  3. Create a /etc/hosts entry for 127.0.0.1 keycloak.keycloak.example.com

  4. Keycloak will be available at http://keycloak.keycloak.example.com:8080

    1. Note: If for some reason Ingress does not work, you can do port forwarding kubectl port-forward keycloak-0 8080
  5. Expose this url via ngrok:

    1. helm install nrgok/ngrok/ngrok
    2. Follow step #3 but replace port 80 with your keycloak path ngrok http http://keycloak.keycloak.example.com:8080 or ngrok http http://localhost:8080
  6. Import the realm into keycloak: Go to platform-console-api, branch_name: lhattamer-no-token-exp db/seeds/argo-keycloak-realm.json

Keycloak admin: username: admin, password: password Keycloak sign in from platform-console: keycloak_user@example.com, password: password

Argo Setup

Follow this guide for the Argo setup

keycloak/argo config

  1. Create the following argo configmap but be sure to replace issuer with your ngrok url and run kubectl apply name_of_configmap_file.yml2.
apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/name":"argocd-cm","app.kubernetes.io/part-of":"argocd"},"name":"argocd-cm","namespace":"argocd"}}
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-cm
  namespace: argocd
data:
  accounts.test_user: apiKey, login
  url: http://argocd.local.com
  oidc.config: |
    name: Keycloak
    issuer: http://d50c-131-150-139-119.ngrok.io/auth/realms/Twilight
    clientID: argocd
    requestedScopes: ["openid", "profile", "email", "groups"]
  1. Create the Following Argo rbac policies and run kubectl apply name_of_rbac_file.yml
apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/name":"argocd-rbac-cm","app.kubernetes.io/part-of":"argocd"},"name":"argocd-rbac-cm","namespace":"argocd"}}
  labels:
    app.kubernetes.io/name: argocd-rbac-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    p, role:org-admin, applications, *, */*, allow
    p, role:org-admin, clusters, get, *, allow
    p, role:org-admin, repositories, get, *, allow
    p, role:org-admin, repositories, create, *, allow
    p, role:org-admin, repositories, update, *, allow
    p, role:org-admin, repositories, delete, *, allow
    g, test_user, role:org-admin
    p, admin, clusters, get, */*, allow
    p, admin, clusters, create, */*, allow
    p, admin, clusters, update, */*, allow
    p, admin, clusters, delete, */*, allow
    p, admin, projects, get, */*, allow
    p, admin, projects, create, */*, allow
    p, admin, projects, update, */*, allow
    p, admin, projects, delete, */*, allow
    p, admin, applications, get, *, allow
    p, admin, applications, create, */*, allow
    p, admin, applications, update, */*, allow
    p, admin, applications, delete, */*, allow
    p, admin, applications, sync, */*, allow
    p, admin, repositories, get, */*, allow
    p, admin, repositories, create, */*, allow
    p, admin, repositories, update, */*, allow
    p, admin, repositories, delete, */*, allow
    p, admin, certificates, get, */*, allow
    p, admin, certificates, create, */*, allow
    p, admin, certificates, update, */*, allow
    p, admin, certificates, delete, */*, allow
    p, admin, accounts, get, */*, allow
    p, admin, accounts, create, */*, allow
    p, admin, accounts, update, */*, allow
    p, admin, accounts, delete, */*, allow
    p, admin, gpgkeys, get, */*, allow
    p, admin, gpgkeys, create, */*, allow
    p, admin, gpgkeys, update, */*, allow
    p, admin, gpgkeys, delete, */*, allow
    g, ArgoCDAdmins, admin
  policy.default: role:''

Keycloak Setup

Setup

Install helm via brew brew install helm Use this guide to set up keycloak via helm

  1. Create this ingress route

  2. Run kubectl apply -f name_of_file.yml

  3. Create a /etc/hosts entry for 127.0.0.1 keycloak.keycloak.example.com

  4. Keycloak will be available at http://keycloak.keycloak.example.com:8080

    1. Note: If for some reason Ingress does not work, you can do port forwarding kubectl port-forward keycloak-0 8080
  5. Expose this url via ngrok:

    1. brew install nrgok/ngrok/ngrok
    2. Follow step #3 but replace port 80 with your keycloak path ngrok http http://keycloak.keycloak.example.com:8080

Dex Keycloak/Github Setup

  1. Edit the argo configmap created in the Keycloak/Argo setup - Step 1.

    apiVersion: v1
    kind: ConfigMap
    metadata:
    annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/name":"argocd-cm","app.kubernetes.io/part-of":"argocd"},"name":"argocd-cm","namespace":"argocd"}}
    labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
    name: argocd-cm
    namespace: argocd
    data:
    url: http://localhost:8080
    admin.enabled: "false"
    dex.config: |
    connectors:
      - type: github
        id: github
        name: Github
        config:
          issuer: https://github.com
          clientID: gitHubClientId
          clientSecret: $oidc.github.clientSecret
      - type: oidc
        id: keycloak
        name: Keycloak
        config:
          issuer: http://e939-2605-a601-afa7-9c00-5cdc-6b67-8d30-1d9b.ngrok.io/auth/realms/Twilight
          clientID: account
          requestedScopes: ["openid", "profile", "email"]
  2. Run $ kubectl apply name_of_configmap_file.yml

  3. Follow these steps for creating a Github client and client secret here.Follow these steps for creating a Github client and client secret here.

  4. Create and apply a secret for your Github and Keycloak client secret.

platform-console-api Notes

Branch name: lhattamer-no-token-exp

Realm name: db/seeds/argo-keycloak-realm.json

  1. In omniauth.rb, tweak the site to your ngrok url. Note: anytime that you restart ngrok you will have to update the path in omniauth.rb along with the argocd configmap.
  2. Sign in via keycloak. The argo_token is saved on the users table.3.

Todo Items for platform-console:

  1. When to save the argo token on the user. Should we save a new token each time that a user logs in with keycloak? See u.argo_token here:
  2. Token expiration, when will the keycloak token expire?

Docs I used for reference:

  1. https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/keycloak/
  2. https://argo-cd.readthedocs.io/en/stable/getting_started/#creating-apps-via-cli
  3. https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/
  4. https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/security.md
  5. https://stackoverflow.com/questions/53550321/keycloak-gatekeeper-aud-claim-and-client-id-do-not-match
  6. https://argo-cd.readthedocs.io/en/stable/developer-guide/api-docs/
  7. https://argo-cd.readthedocs.io/en/stable/getting_started/

Other keycloak notes (you don't need to do this, it's already exported via the realm):

  1. Make the argocd client access type public. Confidential is not needed for local purposes
  2. Web Origins: *
  3. Set the token to expire in 30 days or greater (Under Advanced Settings)
  4. Need to add the argocd issuer to the "aud" claim in the token. To do so, I added a mapper to the account client (Mappers tab). Create new with Mapper type: Audience, Included client audience: argocd. Make sure that Add to access token is turned on.
  5. Note: I don't think we actually need the argocd client. We could have probably just added all of the combined config to the account client.
dginther commented 2 years ago

You have a typo in your ingress: heycloak-http should be keycloak-http

dginther commented 2 years ago

Would it be easier to add the keycloak helm chart to this repo: https://github.com/department-of-veterans-affairs/platform-argocd-local in the way we use them in the application manifests repository, and then allow it to be installed by Argo, rather than installing it first?

RachalCassity commented 2 years ago

Would it be easier to add the keycloak helm chart to this repo: https://github.com/department-of-veterans-affairs/platform-argocd-local in the way we use them in the application manifests repository, and then allow it to be installed by Argo, rather than installing it first?

I am currently using the platform-argocd-local repo. I have Keycloak running locally though. I believe the setup would be the same for the platform repo.