Hello. I'm working on a POC with Cerbos right now ...
# help
s
Hello. I'm working on a POC with Cerbos right now and running into an issue with JWT authentication. Our use case requires us to be able to accept tokens of multiple signature types. In my server configuration, I have two keySets defined. "ks1" is for tokens that come in with a RS256 signature. These requests work perfectly fine, no issues there. "ks2" is for tokens that come in with a RS384 signature. This is where I'm running into issues. When the request comes in, it fails and I see the following error in the logs:
"error":"failed to extract JWT: failed to parse JWT: could not verify message using any of the signatures or keys"}
It was my understanding that Cerbos supported all standard signature types? Not sure if I'm doing something wrong with my configuration. I'm currently using Cerbos version 0.30.0 but have also tried this with 0.29.0 with the same result.
c
Hi. When there is more than one keyset defined in the configuration, you need to specify in the request the keyset that should be used to decode the JWT. Otherwise, Cerbos tries to decode it using the first keyset in the list. https://docs.cerbos.dev/cerbos/latest/configuration/auxdata
s
Hi Charith, I am specifying the keySet to use in my code based on the JWT issuer. If I declare two different keySets (both RS256 and different issuers), I have no trouble authenticating. But as soon as I add the RS384 keyset, Cerbos fails to verify the token
Just to give some more detail: "ks1" is for our own internal system-to-system Cognito token. This is coming in as an RS256 signed token and works as intended. "ks2" is an RS384 signed token that comes from one of our customers when they need to authenticate and use our API. I have an interceptor in my service code that grabs the incoming token, parses and extracts the issuer, then sends the token to Cerbos to validate it. The issuer in the incoming token is the keySet ID, and I've verified that I am specifying the correct keySet in my Cerbos request based on the issuer.
c
Hmm... that's interesting. The library we use for JWT processing supports RS384. I assume the
kid
and
alg
claims are correctly set?
s
Yes, here's an example of the decoded header of the JWT that is failing:
I did take a look through the library you guys are using for JWTs and also verified that they do indeed support RS384. So it's strange that this issue is happening. Really hoping it's something silly on my side 😅
c
Yeah I don't know why it doesn't work. I'll try to reproduce on my side.
s
Awesome, thanks
I'm also free all day so if you want to hop on a call and see it happening on my machine let me know
c
Will do. Thanks!
So there's no problem with decoding RS384 tokens. I tested Cerbos 0.30.0 with a RS384 token generated using https://www.scottbrady91.com/tools/jwt and it worked. I looked into the JWT library to see where the error message you got is generated. It's essentially iterating through the signatures in the JWT and keys in the JWK to see if any of them can verify them (https://github.com/lestrrat-go/jwx/blob/de6bd314bf7ed2525a216fee56f0284d90a436fb/jws/jws.go#L288). Based on that, my guess is that the keyset you're using is not the right one for verifying that token. If you have the Go toolchain installed, you can try verifying one of the tokens manually using https://github.com/lestrrat-go/jwx/blob/de6bd314bf7ed2525a216fee56f0284d90a436fb/cmd/jwx/README.md.
Copy code
echo "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzM4NCIsImtpZCI6IjBlMDg2ZDNjNGZmZDRkNTk1NjI2ZDBmYThkMWI5ODdkIn0.eyJhdWQiOiJodHRwOi8vY2VyYm9zLmRldi90ZXN0In0.iSxFzqipi_9mgGg6PgS84PmwF--mX6Xb62yQCh07__IYWfsv_0MrOXjHl8ftb3paVXuCqE02Oo6DHt3UKPZZzhKF1o9bsYMlOuc7L-1tFeHeMbs9vvfVbJX8mkcroNZ0eXruS4Y51sqQ2FF_rlqA9cbYL4-ilpb4tvkxuZVkBSa1CQ3s_KHIGYy0t1bJxANq51dsGshm74VYSzX7hrLizH27cd81AG_uWnLf3SVQQBkKJfIkX23EmBVNq4L1U8jdd9Y-lFbYnQyt1bJSaP-mFJV09eyPByjYpWzj_-o1Pell-T0Tt48TvL1wfiN7H1eKoZZLuFOzwsselsEMzi9N245IlXhZTkvFbeRC_HQDActoW8cU4JOSLCghsafB3EAYL4l8ipBxg4X1u6SwbdN4i4F604XEVLFwZZUdOm7zbjN0Jl0hnE0hIsYN1kJL8YzHKuEjkqJsNpzACjz3eRsj_wDiJN6-vTad1XSvviNESorIc2r1DTThsSxOAhEZtSHh
" | jwx jws verify --alg=RS384 --key=key.jwk -
s
Hmm, that's strange. We have a service deployed right now that is using our own custom JWT validation library and the token works fine for that, so I don't think there's anything wrong with the keyset. I'm able to validate it using that service just fine, but when I send it to Cerbos it fails
Let me try and see if I can get the jwx cli tool working
👍 1
Okay, so I tested the token using the jwx tool and....it worked 😵‍💫 Not sure what the discrepancy is that's causing it to not work when doing it through Cerbos
c
Very strange 🤔
s
Just to verify if I did it correctly, here's the steps I took: • I requested a new token from the customer • Went to the JKU and copied the key down to my local machine and put it in a json file • Ran this command:
echo "eyJhbGciOiJSUzM4NCIsImprdSI6Imh0dHBzOi8vdmVuZG9yc2VydmljZXMuZXBpYy5jb20vaW50ZXJjb25uZWN0LWFtY3VycHJkLW9hdXRoL2FwaS9lcGljLzIwMTkvU2VjdXJpdHkvT3Blbi9QdWJsaWNLZXlzLzUzMDAxMy81MzAwMTMiLCJraWQiOiJkM2JtbzVIelc2MVRVZ2lrSFpIK0E4VHg0VU9YejJpT3M0S3ZWVTRlTFkwPSIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BsYXRmb3JtZGV2LnNtY3BhcnRuZXJzLmNvbS9wbGF0Zm9ybS9jb25uZWN0ZWQtY2FyZS9lcGljLWNkcy1ob29rcy9jZHMtc2VydmljZXMvY29uZGl0aW9ucyIsImV4cCI6MTY5NjQzOTYzMSwiaWF0IjoxNjk2NDM4NzMxLCJpc3MiOiJodHRwczovL3ZlbmRvcnNlcnZpY2VzLmVwaWMuY29tL2ludGVyY29ubmVjdC1hbWN1cnByZC1vYXV0aC9hcGkvRkhJUi9SNCIsImp0aSI6ImNhN2VjNWZkLWVmNjYtNGMxMi04MWMzLTI4NzJiY2I0NDMzOSIsIm5iZiI6MTY5NjQzODQzMSwic3ViIjoiNWJiZDVjZTYtYTdiNS00Y2ZkLTljZmQtNjg2ODFhYWE1MjM5In0.HjQqL-IDc8HJgBRIiqx6hQvL8V8fAZq4pD37X1rYet5jdeso7XlawdMeBR3nhi2UhyIOQRqelDHUcWVqpNDaz6Yx9xuhAdM_cX9Bji3RnV2m9VSQyT5R_all2Ptish3TWWwXaL-mjchzD-4BWhmMlhe8-vWIDc4eVa4X7M-bN3vRgo9ahQtdmt_W3y4yWVEmMWdPTHdffXun3e7E9EFre9cP7PoSr9ctxvJ3S2xo8Zu-mBs_yZVDFPgaUgCPXBooG9OI-aiK1BC_HjTPpyUdI-UgQ70bCaOpEUq88gk4RxK-c68yLuVFkFcMh5-dfUEr0k9jhii_kfF6ATMRVKUWpA" | jwx jws verify --alg=RS384 --key=keys.json -
And got this as the output:
{"aud":"<https://platformdev.smcpartners.com/platform/connected-care/epic-cds-hooks/cds-services/conditions>","exp":1696439631,"iat":1696438731,"iss":"<https://vendorservices.epic.com/interconnect-amcurprd-oauth/api/FHIR/R4>","jti":"ca7ec5fd-ef66-4c12-81c3-2872bcb44339","nbf":1696438431,"sub":"5bbd5ce6-a7b5-4cfd-9cfd-68681aaa5239"}%
c
Can you configure Cerbos to only have that keyset and try again to see if that makes a difference?
s
Yeah I did try that earlier and still had the same issue
It just doesn't like RS384 tokens for some reason
c
I tested Cerbos with a RS384 token though. In fact, that's the token I pasted above in my example for the CLI. The key is not a secret so I can share it with you so that you can verify it yourself.
s
I wonder if it's an issue with having to go out to a url to get the key?
Let me try it with the key being local in a file
c
Good idea
s
Okay, just verified that I get the same error even when the key is saved locally
c
I tried your token from above with Cerbos set to disable verification. That worked so it's definitely not a parsing error. The issue must be in the key set somehow. If it's safe to do so, can you DM me the public key file you're using. I'll investigate further tomorrow morning.
s
Sure thing, I'll send it to you now. Thanks for the help
c
Thanks for sending the key. I found the problem. The key definition doesn't have an
alg
field. It's optional in the spec but, due to security issues that have arisen from it, most implementations do require it to be present. When I manually added
alg: "RS384"
to the key, Cerbos was able to parse the token successfully.
Do you have any control over the key used by your customer? Are you able to add the
alg
field to it?
s
Ah interesting, thanks for looking into this. Unfortunately it would be very hard to convince them to add that field to their key set. I'm wondering if there's any way to use the
alg
field of the token instead of the key if it's missing?
Nevermind, I see that you already had a similar thought 😄 : https://github.com/cerbos/cerbos/pull/1823
c
Yeah, I assumed you don't have much control over how your customers setup their authentication systems 🙂 Once the PR is merged, until the next Cerbos release, you can try it out using our snapshot build
<http://ghcr.io/cerbos/cerbos:dev|ghcr.io/cerbos/cerbos:dev>
. I'll let you know when it's available.
s
Awesome, thanks so much. I'll try it out and let you know how it goes
Trying to run it using the
dev
tag and I'm getting an error saying that the
insecure
field is not recognized. Here's my
auxData
config:
c
I just merged the PR. The
dev
image has not been published yet 🙂
s
Ah got it. Sorry 😅
c
I'll let you know when it's done building.
👍 1
Build finished. You might need to do
docker pull <http://ghcr.io/cerbos/cerbos:dev|ghcr.io/cerbos/cerbos:dev>
to refresh the cache.
👍 1
s
Cool, I'll give it a go
Looks like it's working 🙂 Thanks so much for the help
c
Glad it worked 🎉
s
Any ETA on when the next release is coming that includes this enhancement?
c
We don't have an exact date yet. It'll probably be towards the end of this month.
s
Got it, I'll keep an eye out for it. Thanks again 🙂
🙇 1