-
Notifications
You must be signed in to change notification settings - Fork 25
Cloud
Pascal S. de Kloe edited this page Jun 19, 2022
·
4 revisions
The Google Cloud exposes keys including a key ID [kid] as a JWKS.
// GoogleIAPKeys resolves the public keys from the Identity-Aware Proxy.
func GoogleIAPKeys() (*jwt.KeyRegister, error) {
resp, err := http.Get("https://www.gstatic.com/iap/verify/public_key-jwk")
if err != nil {
return nil, fmt.Errorf("Google Identity-Aware Proxy public key lookup unavailable: %w", err)
}
defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Google Identity-Aware Proxy public key lookup interrupted: %w", err)
}
var keys jwt.KeyRegister
n, err := keys.LoadJWK(bytes)
if err != nil {
return nil, fmt.Errorf("Google Identity-Aware Proxy public key lookup unusable: %w", err)
}
if n == 0 {
return nil, fmt.Errorf("Google Identity-Aware Proxy public key lookup empty: %s", bytes)
}
return &keys, nil
}
Cloud services can apply tokens from the “assertion” header.
// IMKeys has the recognised credentials for the Identity Management service.
var IMKeys jwt.KeyRegister
// ClientCreds returns the credentials of a client request.
func ClientCreds(req *http.Request) (*jwt.Claims, error) {
// https://cloud.google.com/iap/docs/signed-headers-howto#securing_iap_headers
token := req.Header.Get("X-Goog-IAP-JWT-Assertion")
if token == "" {
return nil, fmt.Errorf("HTTP request from %s without Google Identity-Aware Proxy token", req.RemoteAddr)
}
claims, err := IMKeys.Check([]byte(token))
if err != nil {
return nil, err
}
const wantIssuer = "https://cloud.google.com/iap"
if claims.Issuer != wantIssuer {
return nil, fmt.Errorf("HTTP request from %s has Google Identity-Aware Proxy token issuer %q instead of %q", req.RemoteAddr, claims.Issuer, wantIssuer)
}
const skew = 30 * time.Second
err = claims.AcceptTemporal(time.Now(), skew)
if err != nil {
return nil, fmt.Errorf("HTTP request from %s with bad Google Identity-Aware Proxy token: %w", req.RemoteAddr, err)
}
return claims, nil
}