func ParseTokenFromRequest(r *http.Request, cfg keppel.Configuration, ad keppel.AuthDriver, audience Service) (*Token, *keppel.RegistryV2Error) {
	tokenStr := r.Header.Get("Authorization")
	if !strings.HasPrefix(tokenStr, "Bearer ") {  
		return nil, keppel.ErrUnauthorized.With("no bearer token found in request headers")
	}
	tokenStr = strings.TrimPrefix(tokenStr, "Bearer ")
	var claims TokenClaims
	claims.EmbeddedAuthorization.AuthDriver = ad
	token, err := jwt.ParseWithClaims(tokenStr, &claims, func(t *jwt.Token) (interface{}, error) {
		ourIssuerKey := audience.IssuerKey(cfg)
		ourSigningMethod := ChooseSigningMethod(ourIssuerKey)
		if !equalSigningMethods(ourSigningMethod, t.Method) {
			return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
		}
		return ourIssuerKey.PublicKey().CryptoPublicKey(), nil
	})
	if err != nil {
		return nil, keppel.ErrUnauthorized.With(err.Error())
	}
	if !token.Valid {
		return nil, keppel.ErrUnauthorized.With("token invalid")
	}
	now := time.Now().Unix()
	if !claims.StandardClaims.VerifyExpiresAt(now-3, true) {
		return nil, keppel.ErrUnauthorized.With("token expired")
	}
	if !claims.StandardClaims.VerifyNotBefore(now+3, true) {
		return nil, keppel.ErrUnauthorized.With("token not valid yet")
	}
	publicHost := audience.Hostname(cfg)
	if audience == LocalService {
		if !claims.StandardClaims.VerifyIssuer("keppel-api@"+publicHost, true) {
			return nil, keppel.ErrUnauthorized.With("token has wrong issuer (expected keppel-api@%s)", publicHost)
		}
	}
	if !claims.StandardClaims.VerifyAudience(publicHost, true) {
		return nil, keppel.ErrUnauthorized.With("token has wrong audience (expected %s)", publicHost)
	}
	return &Token{
		Authorization: claims.EmbeddedAuthorization.Authorization,
		Audience:      audience,
		Access:        claims.Access,
	}, nil
}
ParseTokenFromRequest tries to parse the Bearer token supplied in the
request's Authorization header.
package auth
import (
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"
	"github.com/docker/libtrust"
	"github.com/golang-jwt/jwt/v4"
	"github.com/sapcc/keppel/internal/keppel"
	uuid "github.com/satori/go.uuid"
)
type Service int
const (
	LocalService Service = 0
	AnycastService Service = 1
)
func (s Service) Hostname(cfg keppel.Configuration) string {
	switch s {
	case LocalService:
		return cfg.APIPublicURL.Hostname()
	case AnycastService:
		return cfg.AnycastAPIPublicURL.Hostname()
	default:
		panic(fmt.Sprintf("unknown auth service code: %d", s))
	}
}
func (s Service) IssuerKey(cfg keppel.Configuration) libtrust.PrivateKey {
	switch s {
	case LocalService:
		return cfg.JWTIssuerKey
	case AnycastService:
		return *cfg.AnycastJWTIssuerKey
	default:
		panic(fmt.Sprintf("unknown auth service code: %d", s))
	}
}
type Token struct {
	Authorization keppel.Authorization
	Audience Service
	Access []Scope
}
type TokenClaims struct {
	jwt.StandardClaims
	Access                []Scope                      `json:"access"`
	EmbeddedAuthorization keppel.EmbeddedAuthorization `json:"kea"`  
}