istio-ecosystem / authservice

Move OIDC token acquisition out of your app code and into the Istio mesh
Apache License 2.0
217 stars 63 forks source link

authservice does not seem to support JWKS rotation #110

Closed dippynark closed 3 years ago

dippynark commented 4 years ago

Once JWKS rotation occurs (i.e. JWKS endpoint has multiple entries) I am seeing:

IsIDTokenInvalid: `id_token` verification failed: Jwks doesn't have key to match kid or alg from Jwt

in the authservice logs after logging in through my IdP (dex).

My JWKS response looks like:

{
  "keys": [
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "e34738e099d7b289d23f1e024a6cbc955d94745d",
      "alg": "RS256",
      "n": "3kbjJBAcDx98U75Cf8Q9xfQHu9iu-PH6-hoNZMAblszfPVe1WPnLS842hq_F7h4FDcGM4ms2GWbx3cQnswqAoT-urOIoabMyOWvTew5t9NSa4lDOw9Rpw_U7H88s4Jfnv5HCpcXGIHFczQNlQzN4pLjjSauKBaycCiWl9ThnTkCzsw3ayqt5h3fBIzWVDflGxrLVtJME6YpaYovWw31de-sFf31U11ITO-41cWU8-JHQCKsZX16e0UFBHmfTReO3dZzAen7GWKGCfkV_JVZe4gJMdlTeK5PM1_eN_RugVNMeZCIjxq8dBok3c2iXayL7MLXVvGnJrw7cb7hEkZCcbw",
      "e": "AQAB"
    },
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "d3e9962d5b3b51d508c9198b4af00329a51018b7",
      "alg": "RS256",
      "n": "uZuwcgrVGuu3py_Biz1SR75gF6VUIWJM7T08tzCvN5bkbCwqMBBXbqgiPEbu_2l0ZYOMOxfrNb1dSkt3qq8LPac8D2U6WUam26NHPw6BeN-p_ULoy9yEjm58Hu61pIT3J0LnILwiCwxOhnYZRlFr8AqyWKlN3UFM_NKjSjgsHj5QYoE8z_OGtkPw4AqQ4fR42DTNCrzNW332Z7HWAex6FGXGyEykpIcQt81aS7IEbbAQeERdFkXVOM-JF6QV__NkzHxRjQnV6cEftrffKm4VxnjnZGl4I27OZL0Cqz8Hhf6nF-vxaEorJErXLCj7cs8doP-jri9UXtt9KyY3TskDSQ",
      "e": "AQAB"
    }
  ]
}

with my authservice config:

{
  "listen_address": "0.0.0.0",
  "listen_port": "10003",
  "log_level": "trace",
  "threads": 8,
  "chains": [
    {
      "name": "idp_filter_chain",
      "filters": [
      {
        "oidc":
          {
            "authorization_uri": "https://dex.<MY_DOMAIN>/auth",
            "token_uri": "https://dex.<MY_DOMAIN>/token",
            "callback_uri": "https://kiali.<MY_DOMAIN>/oauth/callback",
            "jwks": "{\"keys\":[{\"use\":\"sig\",\"kty\":\"RSA\",\"kid\":\"e34738e099d7b289d23f1e024a6cbc955d94745d\",\"alg\":\"RS256\",\"n\":\"3kbjJBAcDx98U75Cf8Q9xfQHu9iu-PH6-hoNZMAblszfPVe1WPnLS842hq_F7h4FDcGM4ms2GWbx3cQnswqAoT-urOIoabMyOWvTew5t9NSa4lDOw9Rpw_U7H88s4Jfnv5HCpcXGIHFczQNlQzN4pLjjSauKBaycCiWl9ThnTkCzsw3ayqt5h3fBIzWVDflGxrLVtJME6YpaYovWw31de-sFf31U11ITO-41cWU8-JHQCKsZX16e0UFBHmfTReO3dZzAen7GWKGCfkV_JVZe4gJMdlTeK5PM1_eN_RugVNMeZCIjxq8dBok3c2iXayL7MLXVvGnJrw7cb7hEkZCcbw\",\"e\":\"AQAB\"},{\"use\":\"sig\",\"kty\":\"RSA\",\"kid\":\"d3e9962d5b3b51d508c9198b4af00329a51018b7\",\"alg\":\"RS256\",\"n\":\"uZuwcgrVGuu3py_Biz1SR75gF6VUIWJM7T08tzCvN5bkbCwqMBBXbqgiPEbu_2l0ZYOMOxfrNb1dSkt3qq8LPac8D2U6WUam26NHPw6BeN-p_ULoy9yEjm58Hu61pIT3J0LnILwiCwxOhnYZRlFr8AqyWKlN3UFM_NKjSjgsHj5QYoE8z_OGtkPw4AqQ4fR42DTNCrzNW332Z7HWAex6FGXGyEykpIcQt81aS7IEbbAQeERdFkXVOM-JF6QV__NkzHxRjQnV6cEftrffKm4VxnjnZGl4I27OZL0Cqz8Hhf6nF-vxaEorJErXLCj7cs8doP-jri9UXtt9KyY3TskDSQ\",\"e\":\"AQAB\"}]}",
            "client_id": "authservice",
            "client_secret": "YXV0aHNlcnZpY2U=",
            "scopes": [],
            "cookie_name_prefix": "kiali",
            "id_token": {
              "preamble": "Bearer",
              "header": "Authorization"
            },
            "logout": {
              "path": "/authservice_logout",
              "redirect_uri": "https://kiali.<MY_DOMAIN>"
            }
          }
        }
      ]
    }
  ]
}

Resetting dex (in this case) to have just one element in the keys array fixes the issue (after waiting some time which I presume is for Istio to grab the new keys itself, in the interim I see the same error message but returned by the browser).

I assume authservice is only looking at the first entry in the keys array whilst dex is signing new JWTs with the latest key?

I am using the latest authservice image: v0.3.1

cfryanr commented 4 years ago

Interesting, what does your ID token look like? It's supposed to have a kid claim to indicate which of those two signing keys were used.

Relevant section of the spec: https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys

dippynark commented 4 years ago

decoding the returned ID token gives

{
  "alg": "RS256",
  "kid": "eef8392a577a69267eff6401eb45686511bdf070"
}

with payload

{
  "iss": "https://dex.<MY_DOMAIN>",
  "sub": "CgVhZG1pbhIFbG9jYWw",
  "aud": "authservice",
  "exp": 1594452983,
  "iat": 1594366583,
  "nonce": "N0oPtzgdfYn_nl4P9ODw2Q==",
  "at_hash": "cy2ynJcAKn3okh8oBaqjrA",
  "email": "admin@jetstack.io",
  "email_verified": true,
  "name": "admin"
}

with corresponding keys

{
  "keys": [
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "eef8392a577a69267eff6401eb45686511bdf070",
      "alg": "RS256",
      "n": "xBVeIrLRA5tlGw-seIrKmqEUo6YUwEGwO5gtXKKek2a-bTLxTTyvrbUxnkUZrJLyefHnpcduTzVwdvfs9fu5fWNXwd-lal7bd6ebTLzItGsYRAg3PjFwDoG0t-9-eoZKdmn-9b4Y8-AzonlfQRTVMP9QYi67Tm7jNHa03BPS7ko7RpwVwk0HE8gP4ms0zYO-p62oXgLnQxlQ47pVbkFTE10jRaBNTp50nXn928CjQbG_QCWMoxS9AUoBYi37HJkDOW35DLINgkzR48luyn43aCAfOK0Ig06OlJO4w1B70HR5iNhM62AZzcv5Q9glrBG4AhtP1u4lmMF4UfhBy4s2Fw",
      "e": "AQAB"
    },
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "2225a71ca71af3ce6c5a679cc49bf2b1c08739d4",
      "alg": "RS256",
      "n": "6NJt4_O9FHyUPq1SasDrNSIjMD2RkfJaukvPnFGODAhVxZb_0BMRgEvzvDltvidiNPNDyM15wKchGUbqX1iWDg-fflY59h8x4wxyoANmQ3Ik4ItO2-JosnM7EbvYajVude3YskCJyKstjfc4WA_baI3fswyGVBdzQP6ytGe6QTfL8df3Ulw-9KqeghC1JAqjGFPEpKepKmCq9uTBLjllcN7xv0DjOkdAKj1QEMTTHEqv0ZIFM6vvC9JBbCG-ONPF923cjrJXGWdwOhwP1mKaVK1G7kbxkmpPTTgLJ8GZ52SfQ5gh31p3-GZIEtMQRGfVNX2oV-MczVULBxH6MT4hKQ",
      "e": "AQAB"
    },
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "1e68ebd649d697319c1cf393fe72ffd94a50b122",
      "alg": "RS256",
      "n": "zMy8JvPt6Q8ckkikowAQ2aqoOegr84wMC1pU9Y5K0aEz3s6xu2h0TO-PMdI-kVNtkcmqdwjkFVkhWIMyAkZIi3ud-cwYtEqmyetMabpyZkLt0xt2G0-asJHBBWn7wKjLCy3UkWADxdRZ_8KfHerd0qSo0TM3egVKpxqbcEEYsU-9fLm15rgFCHpq_W5k36Pukf5fYbEib3wpcURPUYvl4WDjr2Ipp11I1m3t6LVIgWa--3lEIUD8ucupZo-hLVbYiVCzxNazeS5hjZh1G8Ho7T_Lk3q06MwX9wRHDBDv4yLNFDGMX5YrxRFVqPvyChG1712IH6svQWYByGdkaL5Q_w",
      "e": "AQAB"
    },
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "12295d743e9db3500da8535326a8afae4b383d88",
      "alg": "RS256",
      "n": "ypqGei9yWGLwt8y__dYofWI_kxtkpfhn3LWvb0xmUFVECtFKjE_Hh6oTUmHUceARoJSaMgYUqpHYXn4DVmIudNkBRY4qSVp7x43JMKPOJEU0Q5PnQ0EYgx-ipZo4y8FMPTTFvwcCTpsEqZ76vS3ivfG4mcREYEawQXmt1icITCwsfKAo0hPfz36miPSZKVBsac3fNoynJxnP7hJhrXf0pbx5pTrcQ6n12ZX7S0vyi3P_o3MFvArd-9A17Kkl2143iJi9fw9wkY5cvz5YXW1TejlAb34RGyNPYnyHNc4AYbuEkXqk1wuzG78q4Bxvq8JZCtWu8JbhLwAvWjB3m0Wyhw",
      "e": "AQAB"
    },
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "e13f1003371e84a4bc2bab09fc1ecbe2bf327557",
      "alg": "RS256",
      "n": "pMfly4UAu1gmytcgvcsUWIXKVHzqa6curptR8-VNgwn1_Cz2ONYGRAtJYGkDoMx03ojKQkVC6ReMqI-HnW3NMJMisljfNpfG0FDLKXgjfwyBc4rTfz0oGtwAf-Eq6CTKZgp836PJbSC5mjqh5UYlqlSYYp_7w9n6q292JwrMnmRGDXmG-OOYewU-oXlrwYXduT9MWec9sOHrL1d7-VBORklQzF6SEq9GWI02WqgQxxQRPo-satWIsVaT-hDqQf0q9nEJTYiLUANjLejxbvUwfZfT0u4O44gX6EMAPuOeFztZn3Md89_BKjVCI0-sZpQuHoccrs3xCXUwZFuwLPb7vw",
      "e": "AQAB"
    }
  ]
}

So maybe it's the other round that authservice is only looking at the last key in the array? But I'm being given a JWT corresponding with the first key?

dippynark commented 4 years ago

Also, do you have a recommended method, CLI or another tool for retrieving a JWT locally? I used https://github.com/jetstack/okta-kubectl-auth based off of https://github.com/dexidp/dex/tree/master/cmd/example-app but maybe there's something more generic?

incfly commented 3 years ago

duplicate of https://github.com/istio-ecosystem/authservice/issues/110

dippynark commented 3 years ago

@incfly did you mean to close this issue? This is https://github.com/istio-ecosystem/authservice/issues/110

incfly commented 3 years ago

Sorry @dippynark I meant https://github.com/istio-ecosystem/authservice/issues/34

And to make sure I understand correctly, the IdP can use new keys to sign the id token. But the authservice is using a static preconfigured jwk for verification id token. therefore verificaiton would fail. the issue I linked is sending HTTPS request to the JWKS URI endpoint periodically to fetch updates. That would cover this use case right?

dippynark commented 3 years ago

@incfly hey, yeah #34 would fix this so happy to keep this issue closed