Prerequisites
Fastify version
5.x.x
Plugin version
10.x.x
Node.js version
24.x
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
26.3
Description
fastify-jwt allows the secret plugin option to be a function instead of a static string.
The documentation states that the function will receive request, token, and callback as input.
This works correctly when called from the request or reply context, i.e.
However, verify can be called on the fastify instance outside of a request context too:
fastify.jwt.verify('example token')
When this is done, and a function was passed as secret option, i.e.
const fastify = require('fastify')()
fastify.register(require('@fastify/jwt'), {
secret: function randomSecret(request, token, callback) {
console.log(request)
callback(null, 'random token')
}
})
Then the secret function will be called with the decoded token as first parameter, instead of the fastify request object.
This is happening because in the verify implementation on the fastify instance, the secret option is never treated as a function, and it's passed as is to the the fast-jwt verifier as key.
The verifier itself does support key to be function, but indeed with its own signature.
Whilst this is not a bug per se, I'd say it's an inconsistent or surprising behavior that might cause bugs in consumer code - and might be worth clarifying and uniform it.
PS: this was found whilst investigating the following issue on nearform/fastify-jwt-jwks#54
Link to code that reproduces the bug
https://github.com/paolochiodi/fastify-jwt-secret-as-function-repro
Expected Behavior
The documentation seems to be saying that the function version of the secret is only supported in requests context, but it's easy to miss:
Function based secret is supported by the request.jwtVerify() and reply.jwtSign() methods and is called with request, token, and callback parameters.
I'd suggest a few possible resolutions (from more desirable to less desirable, imo):
- Calls to secret function are uniformed and happen with a consistent, documented signature
- Differences are documented clearly, so consumers are made aware of the scenario
- secret option as function is prohibited and guarded against when using verify on the fastify instance (i.e. throwing an error).
Prerequisites
Fastify version
5.x.x
Plugin version
10.x.x
Node.js version
24.x
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
26.3
Description
fastify-jwt allows the
secretplugin option to be a function instead of a static string.The documentation states that the function will receive request, token, and callback as input.
This works correctly when called from the request or reply context, i.e.
However, verify can be called on the fastify instance outside of a request context too:
When this is done, and a function was passed as
secretoption, i.e.Then the secret function will be called with the decoded token as first parameter, instead of the fastify request object.
This is happening because in the verify implementation on the fastify instance, the secret option is never treated as a function, and it's passed as is to the the fast-jwt verifier as key.
The verifier itself does support key to be function, but indeed with its own signature.
Whilst this is not a bug per se, I'd say it's an inconsistent or surprising behavior that might cause bugs in consumer code - and might be worth clarifying and uniform it.
PS: this was found whilst investigating the following issue on nearform/fastify-jwt-jwks#54
Link to code that reproduces the bug
https://github.com/paolochiodi/fastify-jwt-secret-as-function-repro
Expected Behavior
The documentation seems to be saying that the function version of the secret is only supported in requests context, but it's easy to miss:
I'd suggest a few possible resolutions (from more desirable to less desirable, imo):