BrowZer with Zitadel: "Check that this 'externalId' exists and has case-sensitive match"

Ahhhhh. This is a lead! Your zitadel instance, is it protected with a 3rd party verifiable CA or is it self-signed? I'm going to guess that it's self-signed?

I opted into the "enabled TLS" setup, so both the traffic between Zitadel to the RP and RP to user is TLS protected. The internal Zitadel to RP is self-signed, RP to user is an LE cert.
Same setup goes for my test Keycloak instance.

When you created the extern jwt signer, what jwks url did you configure in OpenZiti? Based on the error, it would seem the zitadel server has a self-signed cert? I've seen " key for kid xx, not found" before, but generally it's because OpenZiti won't connect to the IdP (zitadel) due to an insecure (unverifiable) connection.

Also this error: "no audiences matched the expected audience" is another important clue. What audience is in the jwt and what audience did you use when you made the ext-jwt-signer?

I used the external URL that customers also use, so definitely the LE protected side.
I dont send the traffic to the external IPv4 but the RP IP, so it cant even reach the self-signed cert there.

If by audience you mean the idp_client_id, its the client ID Zitadel shows me for the app I created for the jwt-signer.

Btw, ignore the audience error.

I mentioned I recreated the app in Zitadel, and I swapped the content of the env var to correct the array etc, but I didnt change the audience value of the existing jwt-signer.

I did that now, and this time, we get the expectable error:

{"audience":"xx","authMethod":"ext-jwt","error":"claims property [preferred_username] was not found in the claims","extJwtSignerId":"xx"

That's disappointing for sure. That seems to me to be a zitadel issue, not an OpenZiti-related issue, right?

Do you have an easy enough way to test the token that's returned without going through the browzer mechanics? I ended up using a tool I built to check my jwt while iterating. If you need/want to use it, I could show you how. I think you just need to convince zitadel to get your preferred_username into the jwt :frowning:

The only way I know is what you showed me via the dev tools in the browser.

Keycloak has the nice evaluate feature, especially showing that the preferred_username is there by default. I dont know of a way Zitadel-internal where I can do that.
There is an OIDC playground in the docs where I can request a token, but I dont think thats very helpful: ZITADEL • Identity infrastructure, simplified for you

I'll have to ask in the Zitadel discord, but answers there are slow currently.

Also, I saw you posted our thread there. I am the same guy that opened that thread you posted to :wink:

Yeah, I thought that was you :slight_smile: They do answer, but it does take "a bit" sometimes, yeah. I'll see if i can find a decent oidc tool to use for this stuff. I used our zssh native app. You can download a release from Release 1.0.15 · openziti-test-kitchen/zssh · GitHub

If you do that you would:

  • ziti edge create identity oidctest -o oidctest.jwt

  • ziti edge enroll identity oidctest.jwt

  • use zssh:

    /path/to/zssh \
      -o \
      --oidcIssuer https://zitadel.clint.demo.openziti.org:8558 \
      --clientID client_id_here \
      -c oidctest.json \
      --callbackPort local_port_to_redirect_to \
      doesnt_matter_it_fails_anyway \
      --debug
    

You don't need it to work (but you might like the app?) but you want to use the --debug feature to get the token back.

For example, here's what it looks like on windows

You can then echo it, cut it, jq it and see what it says without going to jwt.io if you want just to see the body:

echo "_some_jwt_here_" | cut -d "." -f2 | base64 -d | jq .
base64: invalid input
{
  "at_hash": "OxrL_L9Y3CFvEieuJ3lYOg",
  "aud": [
    "290222447951675395",
    "290310126118699011",
    "290310781285761027",
    "290222285430718467"
  ],
  "auth_time": 1729601778,
  "azp": "290222447951675395",
  "client_id": "290222447951675395",
  "email": "clint",
  "email_verified": true,
  "exp": 1729645862,
  "family_name": "d",
  "given_name": "Clint",
  "iat": 1729602652,
  "iss": "https://zitadel.clint.demo.openziti.org:8558",
  "locale": null,
  "name": "clint",
  "preferred_username": "dovholuknf",
  "sid": "V1_290423312700407811",
  "sub": "290228191631507459",
  "updated_at": 1729485523,
  "year": 2023
}

Oh you'll need to enable 'dev mode' for this and you'll need to add a redirect url of http://localhost:1234/auth/callback (or whatever --callbackPort you use) for example: