Q:

Verifying Cognito access tokens server-side

I've got a Cognito access token server-side using AdminInitiateAuth (AWS SDK for Go) and I'm storing that in a session cookie.  I'm assuming I need to validate that token on every subsequent request.  Do I need to call out to Cognito for every request, or can I validate the token in my app server-side? 

A:

"OpenID is a decentralized authentication protocol" So you don't have to query a DB server or the Cognito server to verify it because of the asymmetric RSA approach. 
I had the same issue with OpenID tokens.  I'm using Cognito to register to sign-In and sign-up my users.  initially, I could authorize them by using an API gateway authenticator without issues but later I decided to move this in a Kubernetes backend. 
The best idea I found around is from:
How to verify a JWT Token from AWS Cognito in Go?  thread 
and a good Python example from https://github.com/awslabs/aws-support-tools/blob/master/Cognito/decode-verify-jwt/decode-verify-jwt.py

you'll need the public key in order to verify the JWT token

JWT tokens have a based64 URL encoded JSON format with three fields <header>.<payload>.<signature>. 
In the payload field you can find the iss field to search the the "kid" public key before trying to do the verification. 
testparse := strings. Split(tokenid, ".") 
base64decode, err := base64.RawURLEncoding. DecodeString(testparse[1])
fmt. Println("Claims:", string(base64decode))

or better use "github.com/dgrijalva/jwt-go" & "github.com/lestrrat-go/jwx/jwk" to do something like:
jwt. Parse(yourTokenStr, getKeyFunction) 
then in your getKeyFunction() you can do:
fmt. Println("Header: Alg:", token. Header["alg"], ", Kid: ", token. Header["kid"])

claims := token. Claims.(jwt. MapClaims)

// Print unverified claims
for key, value := range claims {
    log. Printf("%s\t: %v\n", key, value)
    if key == "iss" {
        // AWS cognito uses /.well-known/jwks.json path for the pub key
        jwksURL = value.(string) + "/.well-known/jwks.json"
    }
}
...

If your jwt. Parse(yourTokenStr, getKeyFunction) won't return any error the token is valid.  
The errors you can get for example are "Token is expired" or (for my case) a more generic "crypto/rsa: verification error" if it is an expired Token_ID.