I’m developing an integration with Jira Cloud but I am struggling to verify the webhook that comes in when a user installs my app (currently just myself in a developer mode instance).
The documentation states that the public key to validate the incoming requests’ JWT token can be retrieved from the public key CDN (https://connect-install-keys.atlassian.com/
).
However, I’m running into two problems with this:
- The very first time the app is installed in a new instance, no JWT token is provided so obviously I am not able to validate it. I only receive the expected object with instance information as the POST payload (with
clientKey
,publicKey
,sharedSecret
etc.). I have tried all of these params in the payload to see if I could receive the public key with them from the CDN but I get an error stating that the key is not found every time. See screenshot of the headers below (from ngrok)
- If I uninstall the app in the new instance and re-install it to re-test my resolver for the install lifecycle request, I do receive a JWT token. However, I am still not able to verify it. The token that I am receiving is signed using the
HS256
algorithm instead ofRS256
as it is supposed to as listed in the docs. This token is signed with thesharedSecret
that I receive in the payload so I can verify it from that perspective, but of course, I still don’t know if the origin is genuine as this shared key is simply included in the same request.
I’ve received the following JWT token in the Authorization
header (temporary instance and test app so I don’t care about the clientKey
being shared):
JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MGYwMGFkOGY3NDljNDAwNjgwZGFmNDciLCJxc2giOiJmOWI0ZGM0YzE3NzEyMzJmMzhlMGMzMjQzNTNkNTJmYjQ4NzJiNTg3N2QxNDNkNGZhNTI3NmFiNTI0MjExZjVjIiwiaXNzIjoiNTc0ZjhiZGQtOGRjNC0zNWQzLTk1NTgtN2JjZWE0ZTQxZGU2IiwiY29udGV4dCI6e30sImV4cCI6MTYzODI3MTUzMywiaWF0IjoxNjM4MjcwNjMzfQ.R4D8ntSucrhHGJFamhcgeF1JdQUCN7J94CsBMcrd6cQ
This token decodes to (jwt-cli
output):
➜ ~ jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MGYwMGFkOGY3NDljNDAwNjgwZGFmNDciLCJxc2giOiJmOWI0ZGM0YzE3NzEyMzJmMzhlMGMzMjQzNTNkNTJmYjQ4NzJiNTg3N2QxNDNkNGZhNTI3NmFiNTI0MjExZjVjIiwiaXNzIjoiNTc0ZjhiZGQtOGRjNC0zNWQzLTk1NTgtN2JjZWE0ZTQxZGU2IiwiY29udGV4dCI6e30sImV4cCI6MTYzODI3MTUzMywiaWF0IjoxNjM4MjcwNjMzfQ.R4D8ntSucrhHGJFamhcgeF1JdQUCN7J94CsBMcrd6cQ
To verify on jwt.io:
https://jwt.io/#id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MGYwMGFkOGY3NDljNDAwNjgwZGFmNDciLCJxc2giOiJmOWI0ZGM0YzE3NzEyMzJmMzhlMGMzMjQzNTNkNTJmYjQ4NzJiNTg3N2QxNDNkNGZhNTI3NmFiNTI0MjExZjVjIiwiaXNzIjoiNTc0ZjhiZGQtOGRjNC0zNWQzLTk1NTgtN2JjZWE0ZTQxZGU2IiwiY29udGV4dCI6e30sImV4cCI6MTYzODI3MTUzMywiaWF0IjoxNjM4MjcwNjMzfQ.R4D8ntSucrhHGJFamhcgeF1JdQUCN7J94CsBMcrd6cQ
✻ Header
{
"typ": "JWT",
"alg": "HS256"
}
✻ Payload
{
"sub": "60f00ad8f749c400680daf47",
"qsh": "f9b4dc4c1771232f38e0c324353d52fb4872b5877d143d4fa5276ab524211f5c",
"iss": "574f8bdd-8dc4-35d3-9558-7bcea4e41de6",
"context": {},
"exp": 1638271533,
"iat": 1638270633
}
Issued At: 1638270633 11/30/2021, 12:10:33 PM
Expiration Time: 1638271533 11/30/2021, 12:25:33 PM
✻ Signature R4D8ntSucrhHGJFamhcgeF1JdQUCN7J94CsBMcrd6cQ
Since this is a HS256
token, it does not support public/private key signing and the token does not include a kid
to retrieve the public key.
Am I doing anything wrong or overlooking something? It seems to me that the requests that I am receiving do not comply with the documentation.