Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: enhance PACT to understand signed JWT payloads. #356

Open
DanCorderIPV opened this issue Jan 16, 2024 · 5 comments
Open
Labels
enhancement Indicates new feature requests

Comments

@DanCorderIPV
Copy link

We are using pact to test endpoints that return signed JWTs. As JWTs are not plain json we can't specify the structure of the data using newJsonBody() etc which makes our tests quite brittle.

Signed JWTs are strings of the form <header>.<body>.<signature> where each of the three parts is base64 encoded. It would be great if the pact framework could support something like this when specifying a pact (JVM syntax):

...
.body(newJwt((jwt) -> {
    jwt.headerAlgorithm(JwsSigningAlgorithm.ES256);
    jwt.signingKeys("publicKey", "privateKey");
    jwt.payload(newJsonBody((jb) -> {
        jb.stringValue("name", "Joe Bloggs");
    }).build());
}).build())
...

https://jwt.io/ is very useful for experimenting with and validating JWTs

@mefellows
Copy link
Member

A few other questions:

  1. Do you want to be able to simply verify the JWT is valid, or verify that the payload of the JWT (e.g. name in your example) are present and match any given matchers?
  2. Presumably we would also want to support this in headers and not just the body

@mefellows mefellows added the enhancement Indicates new feature requests label Jan 16, 2024
@rholshausen
Copy link
Contributor

This could be implemented as a plugin

@DanCorderIPV
Copy link
Author

Sorry for the delay replying, I didn't see a notification - probably gone in the spam.

Anyway:

  1. I would like to be able to use the existing JSON matching code within the body of the JWT. This also seems more in keeping with the existing code.
  2. I assume you mean the JWT header. I'm not a JWT expert, but I think that the header values are more limited in what they can be so allowing full matching may not be necessary. To fully validate/generate a valid JWT the framework would also need to understand the header block to use the correct signing algorithm. I'm not sure if you'd want to support this (at least not immediately) as it seems like quite a lot of work to allow all the various signing algorithms that JWTs can use.

@DanCorderIPV
Copy link
Author

I've just looked at the plugin documentation that I could find and it looks like the pact would look more like this?

    return builder
      .usingPlugin("jwt")
      .expectsToReceive("request for a JWT", "core/interaction/http")
      .with(Map.of(
        "request.path", "/getCredential",
        "response.privateSigningKey", "privateKeyValue",
        "response.publicSigningKey", "publicKeyValue",
        "response.status", "200",
        "response.contents", Map.of(
          "content-type", "application/jwt",
          "$.header.alg", "matching(???, 'ES256')",    <-- Would need to have a list of valid values/enum
          "$.body.name", "matching(string,'Joe Bloggs')",
        )
      ))
      .toPact();

That would work, but seems less user friendly and type safe.

@mefellows
Copy link
Member

Yes, the "raw" (my words) plugin interface is not as typesafe, but I believe there is nothing stopping anyone from creating a typesafe wrapper over the top of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Indicates new feature requests
Projects
None yet
Development

No branches or pull requests

3 participants