'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued


#1

I’m currently trying to integrate Drupal with GitHub Integrations. I’m using php-github-api but can’t seem to get past the JWT generation. I get the following message:

'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued

However when I inspect the token being sent to github, it looks completely fine. The decoded relevant json looks like this:

{
  "iss": "1883",
  "iat": 1490661340,
  "exp": 1490661400
}

As you can see from the JSON dump, the iat is an integer. The error message does mention that the time should be when the assertion was issued. However, as EPOCH integers don’t provide a way to represent timezone, I’m not sure how I could be more accurate. I’ve set the timezone to UTC.

Unfortunately, things are still failing. I was able to validate the JWT in https://jwt.io/ so I’m out of options as to why github is failing this request??


#2

Just fyi, i vaguely remember having a similar issue, but the problem was unrelated to whether iat was an integer or not.

I’d keep looking elsewhere for problems, here’s my implementation in Go: https://github.com/bradleyfalzon/ghinstallation/blob/master/transport.go#L96


#3

I can replicate this with curl:

curl -v -H "Host: api.github.com" -H "User-Agent: php-github-api (http://github.com/KnpLabs/php-github-api)" -H "Accept: application/vnd.github.machine-man-preview" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxODgzIiwiaWF0IjoxNDkwNjY4MzExLCJleHAiOjE0OTA2NjgzNzF9.yNpoEp9tQd25oPHybPG6m3cyyMEafxscBvbdHbE-GpbR8mkrgYkRQ-tXSWGQGa57cDpIjXvxsA0RCtThZHUGbsUsJNQyCzaIyYHLHAxU9ZaRMb5TK72hiP7J5q6iLBl6bCo5oa4utL71rFYRsClK1RTEaheh2YTTTrsrUbjn4EGT23nRBS3mX0YSicAmE1F8sMN4oy3s4PNnW2Qa8zLViXkbO2YllhQinmeRWmTqJDeEMB6kjBHgaBIyi89SXSKZPgEClfcb4_2oU4sOiW-8JlpnNcEZ2yT7Tl6nqZ3zgSafL9XN_l-wIBN-iuHRGmhoxv-GxAgqycZOcEBHrH4F4A" https://api.github.com/installations/1883/access_tokens
*   Trying 192.30.253.116...
* TCP_NODELAY set
* Connected to api.github.com (192.30.253.116) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.github.com
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> GET /installations/1883/access_tokens HTTP/1.1
> Host: api.github.com
> User-Agent: php-github-api (http://github.com/KnpLabs/php-github-api)
> Accept: application/vnd.github.machine-man-preview
> Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxODgzIiwiaWF0IjoxNDkwNjY4MzExLCJleHAiOjE0OTA2NjgzNzF9.yNpoEp9tQd25oPHybPG6m3cyyMEafxscBvbdHbE-GpbR8mkrgYkRQ-tXSWGQGa57cDpIjXvxsA0RCtThZHUGbsUsJNQyCzaIyYHLHAxU9ZaRMb5TK72hiP7J5q6iLBl6bCo5oa4utL71rFYRsClK1RTEaheh2YTTTrsrUbjn4EGT23nRBS3mX0YSicAmE1F8sMN4oy3s4PNnW2Qa8zLViXkbO2YllhQinmeRWmTqJDeEMB6kjBHgaBIyi89SXSKZPgEClfcb4_2oU4sOiW-8JlpnNcEZ2yT7Tl6nqZ3zgSafL9XN_l-wIBN-iuHRGmhoxv-GxAgqycZOcEBHrH4F4A
>
< HTTP/1.1 401 Unauthorized
< Server: GitHub.com
< Date: Tue, 28 Mar 2017 02:29:54 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 164
< Status: 401 Unauthorized
< X-GitHub-Media-Type: github.machine-man-preview
< Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
< Access-Control-Allow-Origin: *
< Content-Security-Policy: default-src 'none'
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-XSS-Protection: 1; mode=block
< X-GitHub-Request-Id: DCC0:4603:3BFE1B:4D0E75:58D9CAA1
<
* Curl_http_done: called premature == 0
* Connection #0 to host api.github.com left intact
{"message":"'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued","documentation_url":"https://developer.github.com/v3"}

The response now returns 404 since the time has passed but as you can see above, it did response with a 401 at first. You can pump the contents of the Bearer into jwt.io to see the output and validate that the message coming back from github is not the problem (whatever the problem might be).


#4

I believe it should also be a POST not a GET, as per: https://developer.github.com/early-access/integrations/authentication/#as-an-installation

Can you double check that?


#5

you’re right! Buy that was my mistake in replicating the issue with curl. Issue still present when using POST:

curl -X POST -v -H "Host: api.github.com" -H "User-Agent: php-github-api (http://github.com/KnpLabs/php-github-api)" -H "Accept: application/vnd.github.machine-man-preview" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxODgzIiwiaWF0IjoxNDkwNjczNzA5LCJleHAiOjE0OTA2NzM3Njl9.u9p3usYQiy_ZUzKR_pqlFDLgmsEUQF-fCW2g-Tu8niv2UTecOJHpX-AzM4Zrcdizr4nYqcSCnSVc7AIfrkTjtqp_qAt83G37OUtZtUyUsagHw9M3wglCllbH5S56ptKvLv7uAZ61yYQF6Yd1yPb-jHaNsreuXx8y2nFZPMvkUjhuuPjMyYoToBOBZtFbE_1qNNa266g_0gKEoDATWDgAzpu6ktjS7V-6HDn3jGLz5IxmJ376e4TNYL6KE-nkh8eckXtULYSnQwt3XLhq8hnKIjC8LHxYqVua-3mo_jFy2G7MIAAHVlfG8GBk9O91KVI164dv4JDUR28bqH-JcRl3dQ" https://api.github.com/installations/1883/access_tokens
*   Trying 192.30.253.117...
* TCP_NODELAY set
* Connected to api.github.com (192.30.253.117) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.github.com
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> POST /installations/1883/access_tokens HTTP/1.1
> Host: api.github.com
> User-Agent: php-github-api (http://github.com/KnpLabs/php-github-api)
> Accept: application/vnd.github.machine-man-preview
> Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxODgzIiwiaWF0IjoxNDkwNjczNzA5LCJleHAiOjE0OTA2NzM3Njl9.u9p3usYQiy_ZUzKR_pqlFDLgmsEUQF-fCW2g-Tu8niv2UTecOJHpX-AzM4Zrcdizr4nYqcSCnSVc7AIfrkTjtqp_qAt83G37OUtZtUyUsagHw9M3wglCllbH5S56ptKvLv7uAZ61yYQF6Yd1yPb-jHaNsreuXx8y2nFZPMvkUjhuuPjMyYoToBOBZtFbE_1qNNa266g_0gKEoDATWDgAzpu6ktjS7V-6HDn3jGLz5IxmJ376e4TNYL6KE-nkh8eckXtULYSnQwt3XLhq8hnKIjC8LHxYqVua-3mo_jFy2G7MIAAHVlfG8GBk9O91KVI164dv4JDUR28bqH-JcRl3dQ
>
< HTTP/1.1 401 Unauthorized
< Server: GitHub.com
< Date: Tue, 28 Mar 2017 03:59:49 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 164
< Status: 401 Unauthorized
< X-GitHub-Media-Type: github.machine-man-preview
< Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
< Access-Control-Allow-Origin: *
< Content-Security-Policy: default-src 'none'
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-XSS-Protection: 1; mode=block
< X-GitHub-Request-Id: DD01:4604:464718:5A9384:58D9DFB4
<
* Curl_http_done: called premature == 0
* Connection #0 to host api.github.com left intact
{"message":"'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued","documentation_url":"https://developer.github.com/v3"}

#6

I think I have solved it. My macbook pro was running 4 minutes fast as it was using clock settings from the US rather than from Asia (I’m in New Zealand). This time difference also impacted my VM I was running the code from and must have also affected github’s validation of the issue date.


#7

We also noticed this issue with our production integration over the last weeks, with a handful of our requests failing while some work as expected - before that all of our JWT tokens worked as expected.

@jmilas there’s any chance that this is related to anything on GitHub’s side?


#8

@fiasco @lucasmazza We’re a little late to this thread, are you still experiencing any issues with this?


#9

Similar to @fiasco we noticed a clock skew on our servers and the error was gone after we fixed the time difference.


#10

I’m still getting this error. Anyone know why?


#11

I’m getting this error everytime on my development machine.
The project is running in a Docker container, and each time is out-of-sync after my laptop wakes up from hibernation.

@anuccio1 this is probably linked somehow to a glimpse in the date/time of your server, you should double-check.


#12

That’s a bug in Docker for Windows or Mac, related to Hyper-V and Xhyve. It goes away if you run it directly on a Linux system.


#13

I also face this problem. And it was so strange that my succeeded code turned to failing the other day! Any integer value is refused…


#14

I found out one solution. To set the “past time” to iat solves the problem.

utcnow = datetime.utcnow() + timedelta(seconds=-5)
duration = timedelta(seconds=30)
payload = {
    "iat": utcnow,
    "exp": utcnow + duration,
    "iss": 2510
}

#15

I am continuously getting the same error. Any help is greatly appreciated.

My token claim looks like this :
{
“iat”: “63664290288”,
“exp”: “315537897600”,
“iss”: “204890”
}
‘iat’ is an integer but still getting the same error. My C# code is as follows that build the claim :
var claims = new List
{
new Claim(“iat”, ((Int64)(DateTime.UtcNow.AddSeconds(-5).Subtract(DateTime.MinValue)).TotalSeconds).ToString()),
new Claim(“exp”, (DateTime.MaxValue.Subtract(DateTime.MinValue)).TotalSeconds.ToString()),
new Claim(“iss”, “204890”)
};


#16

I was able to resolve this by ensuring that the total seconds are calculated using 1/1/1970 ( Linux time ) as compared to DateTime.Min. This worked :

var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var issueTime = DateTime.UtcNow;

        var iat = (Int64)issueTime.Subtract(utc0).TotalSeconds;
        var exp = (Int64)issueTime.AddMinutes(10).Subtract(utc0).TotalSeconds; 
        var payload = new
        {
            iss = 12768,
            exp = exp,
            iat = iat
        };

#17

I ran into this issue too. The cause seems to be the UTC time on my dev machine was a minute faster than the actual time (or the time on github’s servers).

The solution was to sync my my local clock to the correct time, and it all started working. Essentially I was sending an iat that was in the future!

It looks like the error message being returned from github is wrong, it should really be updated to reflect what is actually causing the problem - this would have saved me a bunch of time figuring out what the issue really was.