Enrollment succeeds with expired JWT

I am able to enroll an identity with a JWT that has expired:

$ ./bin/ziti edge list identities 'name="client1"' -j | jq -r '.data[].enrollment.ott.expiresAt'
2024-11-20T02:50:37.295Z

$ date -u -d "@$(cut -f2 -d. /mnt/c/tmp/client1.jwt | base64 -d 2>/dev/null | jq -r '.exp')"
Wed Nov 20 02:50:37 AM UTC 2024

$ date -u
Wed Nov 20 11:41:12 PM UTC 2024

>"C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge\ziti-edge-tunnel.exe" enroll --jwt C:\tmp\client1.jwt --identity C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\NetFoundry\client1.json
StartServiceCtrlDispatcher failed (1063)
(24848)[        0.000]    INFO ziti-sdk:utils.c:201 ziti_log_set_level() set log level: root=3/INFO
(24848)[        0.000]    INFO ziti-sdk:utils.c:170 ziti_log_init() Ziti C SDK version 1.0.9 @g5cbbb5c(HEAD) starting at (2024-11-20T23:55:31.716)
(24848)[        0.000]    INFO ziti-sdk:ziti_enroll.c:88 ziti_enroll() Ziti C SDK version 1.0.9 @g5cbbb5c(HEAD) starting enrollment at (2024-11-20T23:55:31.719)

$ ./bin/ziti edge list identities 'name="client1"' -j | jq -r '.data[].enrollment'
{}

The ziti controller is at v1.1.15. and I am using Windows tunneller.

Is this a bug? Or is there a configuration setting that allows this?

It produced a .json file? That definitely surprises me, I'm certain I have had JWTs expire in the past. I'll test it out locally to see what happens as well.

Yes @TheLumberjack . It produced a valid json with the certs and ca.

I'm testing it out locally... 5m is the shortest time one can set the jwt expiration to. I'll report back in a bit. :slight_smile:

I've filed this issue and will check with @andrew.martinez tomorrow... expired JWTs are allowed to enroll · Issue #2559 · openziti/ziti · GitHub

the ziti CLI will check the token before attempting to enroll the jwt and will refuse to attempt to enroll the JWT reporting:

ziti edge enroll c:\temp\expired-jwt\ziti-id.jwt
Usage:
  ziti edge enroll path/to/jwt [flags]

Flags:
      --ca string         Additional trusted certificates
  -c, --cert string       The certificate to present when establishing a connection.
  -h, --help              help for enroll
  -n, --idname string     Names the identity. Ignored if not 3rd party auto enrollment
  -j, --jwt string        Enrollment token (JWT file). Required
  -k, --key string        The key to use with the certificate. Optionally specify the engine to use. supported engines: [parsec]
  -a, --keyAlg RSA|EC     Crypto algorithm to use when generating private key (default RSA)
  -o, --out string        Output configuration file.
  -p, --password string   Password for updb enrollment, prompted if not provided and necessary
      --rm                Remove the JWT on success
  -u, --username string   Username for updb enrollment, prompted if not provided and necessary
  -v, --verbose           Enable verbose logging


failed to parse JWT: token has invalid claims: token is expired

Assuming @andrew.martinez agrees with the implementation, we'll file an issue with the ziti-tunneler-sdk-c repo to do the same thing as the ziti CLI.

Thanks for reporting this

Thank you @TheLumberjack.

It would seem to me that the controller should also block this enrollment attempt (since it knows that the client JWT has expired)? Or am I mis-understanding the flow?

Yes. It's already in the process of getting fixed in the controller. I'll be making a bug for the ziti-edge-tunnel to check the token too...

All enrollment clients should verify their JWT isn't expired before using. The JWT is used for trust relationship building, so using expired ones, is not something we should do.

The controller, no matter what, should also not be allowing expired enrollments. There is currently a disconnect between the enrollment and the minted JWT in terms of expiration.

I have already submitted a fixes and tests for this case and related cases.