diff --git a/CMakeModules/testing_cpp.cmake b/CMakeModules/testing_cpp.cmake
index 23a4457ac3af624949eeba0f4b3c9a55900820c3..63dae68e4cf2c706b2a245cbbbd8ef8de9419126 100644
--- a/CMakeModules/testing_cpp.cmake
+++ b/CMakeModules/testing_cpp.cmake
@@ -4,6 +4,7 @@ endif ()
 
 set (TOKENS "ASAPO_TEST_RW_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTkyMXJqaXB0MzVja3MzYTEwZyIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJyZWFkIiwid3JpdGUiXX19.3PFdG0f48yKrOyJwPErYcewpcbZgnd8rBmBphw_kdJ0")
 set (TOKENS "${TOKENS};ASAPO_CREATE_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTkyYzMzaXB0Mzdkb3IzYmZjZyIsInN1YiI6ImFkbWluIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZXMiOlsiY3JlYXRlIl19fQ.AI41cZ7dZL0g-rrdKIQgd7ijjzuyH1Fm0xojCXwLNBo")
+set (TOKENS "${TOKENS};ASAPO_REVOKE_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjNWFxOHVyaXB0MzV0aG9raDFwMCIsInN1YiI6ImFkbWluIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZXMiOlsicmV2b2tlIl19fQ.GNje7w6biX0-ynltRr81p5SBSWwmKdDwGfs-adb094Q")
 set (TOKENS "${TOKENS};C20180508_000_COM20181_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTkyaDRiaXB0Mzd1cGo1aDdlMCIsInN1YiI6ImJ0X2MyMDE4MDUwOC0wMDAtQ09NMjAxODEiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJyZWFkIiwid3JpdGUiXX19.yONpjW2ybZMc9E9Eu4Hmn1roVR-mxf2OQQyXfnel5C8")
 set (TOKENS "${TOKENS};BT11000015_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTkyajZqaXB0MzA3aHU1amwxZyIsInN1YiI6ImJ0XzExMDAwMDE1IiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZXMiOlsicmVhZCJdfX0.kVs669HAS4sj9VAZk8pWTLrYNQp46mOnH4id4-_qd9g")
 set (TOKENS "${TOKENS};BT11000016_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTkyajQzaXB0MzA3OWxwc3Z2ZyIsInN1YiI6ImJ0XzExMDAwMDE2IiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZXMiOlsicmVhZCJdfX0.mpTVGtcdR0l4NaeHFTf16iWrfMYaLzh2pAjN5muil6Q")
diff --git a/authorizer/src/asapo_authorizer/server/authorize.go b/authorizer/src/asapo_authorizer/server/authorize.go
index e8faa9caaef9e2fa14a35f58561579e23fe3157d..aaea9b0951278067534f4f6b1486dbd84e3340af 100644
--- a/authorizer/src/asapo_authorizer/server/authorize.go
+++ b/authorizer/src/asapo_authorizer/server/authorize.go
@@ -14,9 +14,9 @@ import (
 type SourceCredentials struct {
 	BeamtimeId string
 	Beamline   string
-	DataSource     string
+	DataSource string
 	Token      string
-	Type 	   string
+	Type       string
 }
 
 type authorizationRequest struct {
@@ -26,15 +26,14 @@ type authorizationRequest struct {
 
 func getSourceCredentials(request authorizationRequest) (SourceCredentials, error) {
 
-
 	vals := strings.Split(request.SourceCredentials, "%")
-	nvals:=len(vals)
+	nvals := len(vals)
 	if nvals < 5 {
 		return SourceCredentials{}, errors.New("cannot get source credentials from " + request.SourceCredentials)
 	}
 
-	creds := SourceCredentials{Type:vals[0], BeamtimeId: vals[1], Beamline: vals[2], Token:vals[nvals-1]}
-	creds.DataSource=strings.Join(vals[3:nvals-1],"%")
+	creds := SourceCredentials{Type: vals[0], BeamtimeId: vals[1], Beamline: vals[2], Token: vals[nvals-1]}
+	creds.DataSource = strings.Join(vals[3:nvals-1], "%")
 	if creds.DataSource == "" {
 		creds.DataSource = "detector"
 	}
@@ -54,7 +53,6 @@ func getSourceCredentials(request authorizationRequest) (SourceCredentials, erro
 	return creds, nil
 }
 
-
 func splitHost(hostPort string) string {
 	s := strings.Split(hostPort, ":")
 	return s[0]
@@ -95,7 +93,7 @@ func beamtimeMetaFromMatch(match string) (common.BeamtimeMeta, error) {
 		return common.BeamtimeMeta{}, errors.New("skipped fodler")
 	}
 
-	bt.OfflinePath = common.Settings.RootBeamtimesFolder+string(filepath.Separator)+match
+	bt.OfflinePath = common.Settings.RootBeamtimesFolder + string(filepath.Separator) + match
 	bt.Beamline, bt.BeamtimeId = vars[2], vars[5]
 
 	return bt, nil
@@ -107,10 +105,10 @@ func findBeamtimeInfoFromId(beamtime_id string) (common.BeamtimeMeta, error) {
 	matches, err := filepath.Glob(common.Settings.RootBeamtimesFolder + pattern + beamtime_id)
 
 	if err != nil || len(matches) == 0 {
-		return common.BeamtimeMeta{}, errors.New("Cannot find beamline for "+beamtime_id)
+		return common.BeamtimeMeta{}, errors.New("Cannot find beamline for " + beamtime_id)
 	}
 
-	for _, match := range (matches) {
+	for _, match := range matches {
 		btInfo, err := beamtimeMetaFromMatch(match)
 		if err != nil {
 			continue
@@ -119,12 +117,12 @@ func findBeamtimeInfoFromId(beamtime_id string) (common.BeamtimeMeta, error) {
 			return btInfo, nil
 		}
 	}
-	return common.BeamtimeMeta{}, errors.New("Cannot find beamline for "+beamtime_id)
+	return common.BeamtimeMeta{}, errors.New("Cannot find beamline for " + beamtime_id)
 }
 
-func findMetaFileInFolder(beamline string,iscommissioning bool) (string, string, error){
+func findMetaFileInFolder(beamline string, iscommissioning bool) (string, string, error) {
 	sep := string(filepath.Separator)
-	var pattern,folder string
+	var pattern, folder string
 	if !iscommissioning {
 		pattern = "beamtime-metadata-*.json"
 		folder = "current"
@@ -135,18 +133,18 @@ func findMetaFileInFolder(beamline string,iscommissioning bool) (string, string,
 	online_path := common.Settings.CurrentBeamlinesFolder + sep + beamline + sep + folder
 	matches, err := filepath.Glob(online_path + sep + pattern)
 	if err != nil {
-		return "","", err
+		return "", "", err
 	}
 	if len(matches) != 1 {
-		return "","", errors.New("should be one beamtime-metadata file in folder")
+		return "", "", errors.New("should be one beamtime-metadata file in folder")
 	}
-	return matches[0],online_path, nil
+	return matches[0], online_path, nil
 
 }
 
-func findBeamtimeMetaFromBeamline(beamline string,iscommissioning bool) (meta common.BeamtimeMeta, err error) {
-	fName,online_path, err := findMetaFileInFolder(beamline,iscommissioning)
-	if (err != nil) {
+func findBeamtimeMetaFromBeamline(beamline string, iscommissioning bool) (meta common.BeamtimeMeta, err error) {
+	fName, online_path, err := findMetaFileInFolder(beamline, iscommissioning)
+	if err != nil {
 		return common.BeamtimeMeta{}, err
 	}
 
@@ -155,11 +153,11 @@ func findBeamtimeMetaFromBeamline(beamline string,iscommissioning bool) (meta co
 	} else {
 		meta, err = beamtimeMetaFromJson(fName)
 	}
-	if (err != nil) {
+	if err != nil {
 		return common.BeamtimeMeta{}, err
 	}
 
-	if meta.BeamtimeId == "" || meta.OfflinePath=="" || meta.Beamline == ""{
+	if meta.BeamtimeId == "" || meta.OfflinePath == "" || meta.Beamline == "" {
 		return common.BeamtimeMeta{}, errors.New("cannot set meta fields from beamtime file")
 	}
 
@@ -172,23 +170,23 @@ func alwaysAllowed(creds SourceCredentials) (common.BeamtimeMeta, bool) {
 		if pair.BeamtimeId == creds.BeamtimeId {
 			pair.DataSource = creds.DataSource
 			pair.Type = creds.Type
-			pair.AccessTypes = []string{"read","write"}
+			pair.AccessTypes = []string{"read", "write"}
 			return pair, true
 		}
 	}
 	return common.BeamtimeMeta{}, false
 }
 
-func authorizeByHost(host_ip, beamline string) (error) {
-	filter := strings.Replace(common.Settings.Ldap.FilterTemplate,"__BEAMLINE__",beamline,1)
-	allowed_ips, err := ldapClient.GetAllowedIpsForBeamline(common.Settings.Ldap.Uri,common.Settings.Ldap.BaseDn, filter)
+func authorizeByHost(host_ip, beamline string) error {
+	filter := strings.Replace(common.Settings.Ldap.FilterTemplate, "__BEAMLINE__", beamline, 1)
+	allowed_ips, err := ldapClient.GetAllowedIpsForBeamline(common.Settings.Ldap.Uri, common.Settings.Ldap.BaseDn, filter)
 	if err != nil {
 		log.Error("cannot get list of allowed hosts from LDAP: " + err.Error())
 		return err
 	}
 
-	if (!utils.StringInSlice(splitHost(host_ip),allowed_ips)) {
-		err_string := "beamine " +beamline+" not allowed for host " + host_ip
+	if !utils.StringInSlice(splitHost(host_ip), allowed_ips) {
+		err_string := "beamine " + beamline + " not allowed for host " + host_ip
 		log.Error(err_string)
 		return errors.New(err_string)
 	}
@@ -199,57 +197,73 @@ func canUseHostAuthorization(creds SourceCredentials) bool {
 	return len(creds.Token) == 0
 }
 
+func checkTokenRevoked(tokenId string) (err error) {
+	revoked, err := store.IsTokenRevoked(tokenId)
+	if err != nil {
+		return &common.ServerError{utils.StatusServiceUnavailable, err.Error()}
+	}
+	if revoked {
+		return errors.New("token was revoked")
+	}
+	return nil
+}
+
 func checkToken(token string, subject_expect string) (accessTypes []string, err error) {
 	var extra_claim structs.AccessTokenExtraClaim
-	claim,err := Auth.UserAuth().CheckAndGetContent(token,&extra_claim)
-	if err!=nil {
-		return nil,err
+	claim, err := Auth.UserAuth().CheckAndGetContent(token, &extra_claim)
+	if err != nil {
+		return nil, err
+	}
+
+	err = checkTokenRevoked(claim.Id)
+	if err != nil {
+		return nil, err
 	}
 
-	if extra_claim.AccessTypes==nil || len(extra_claim.AccessTypes)==0 {
-		return nil,errors.New("missing access types")
+	if extra_claim.AccessTypes == nil || len(extra_claim.AccessTypes) == 0 {
+		return nil, errors.New("missing access types")
 	}
 
-	if claim.Subject!=subject_expect {
-		return nil,errors.New("wrong token for "+subject_expect)
+	if claim.Subject != subject_expect {
+		return nil, errors.New("wrong token for " + subject_expect)
 	}
-	return extra_claim.AccessTypes,err
+	return extra_claim.AccessTypes, err
 }
 
 func authorizeByToken(creds SourceCredentials) (accessTypes []string, err error) {
-	subject_expect:=""
-	if (creds.BeamtimeId != "auto") {
+	subject_expect := ""
+	if creds.BeamtimeId != "auto" {
 		subject_expect = utils.SubjectFromBeamtime(creds.BeamtimeId)
 	} else {
 		subject_expect = utils.SubjectFromBeamline(creds.Beamline)
 	}
-	return checkToken(creds.Token,subject_expect)
+	return checkToken(creds.Token, subject_expect)
 }
 
 func iscommissioning(beamtime string) bool {
-	return len(beamtime)>0 && beamtime[0]=='c'
+	return len(beamtime) > 0 && beamtime[0] == 'c'
 }
 
 func findMeta(creds SourceCredentials) (common.BeamtimeMeta, error) {
 	var err error
 	var meta common.BeamtimeMeta
-	if (creds.BeamtimeId != "auto") {
+	if creds.BeamtimeId != "auto" {
 		meta, err = findBeamtimeInfoFromId(creds.BeamtimeId)
-		if (err == nil ) {
-			meta_onilne, err_online := findBeamtimeMetaFromBeamline(meta.Beamline,iscommissioning(creds.BeamtimeId))
+		if err == nil {
+			meta_onilne, err_online := findBeamtimeMetaFromBeamline(meta.Beamline, iscommissioning(creds.BeamtimeId))
 			if err_online == nil && meta.BeamtimeId == meta_onilne.BeamtimeId {
 				meta.OnlinePath = meta_onilne.OnlinePath
 			}
 		}
 	} else {
-		meta, err = findBeamtimeMetaFromBeamline(creds.Beamline,false)
+		meta, err = findBeamtimeMetaFromBeamline(creds.Beamline, false)
 	}
 
 	if creds.Type == "processed" {
 		meta.OnlinePath = ""
 	}
 
-	if (err != nil) {
+	if err != nil {
 		log.Error(err.Error())
 		return common.BeamtimeMeta{}, err
 	}
@@ -262,32 +276,32 @@ func findMeta(creds SourceCredentials) (common.BeamtimeMeta, error) {
 
 func authorizeMeta(meta common.BeamtimeMeta, request authorizationRequest, creds SourceCredentials) (accessTypes []string, err error) {
 	accessTypes = nil
-	if creds.Type=="raw" && meta.OnlinePath=="" {
-		err_string := "beamtime "+meta.BeamtimeId+" is not online"
+	if creds.Type == "raw" && meta.OnlinePath == "" {
+		err_string := "beamtime " + meta.BeamtimeId + " is not online"
 		log.Error(err_string)
-		return nil,errors.New(err_string)
+		return nil, errors.New(err_string)
 	}
 
 	if creds.Beamline != "auto" && meta.Beamline != creds.Beamline {
 		err_string := "given beamline (" + creds.Beamline + ") does not match the found one (" + meta.Beamline + ")"
 		log.Debug(err_string)
-		return nil,errors.New(err_string)
+		return nil, errors.New(err_string)
 	}
 
 	if canUseHostAuthorization(creds) {
 		if err := authorizeByHost(request.OriginHost, meta.Beamline); err != nil {
-			return nil,err
+			return nil, err
 		}
 		if creds.Type == "raw" {
-			accessTypes = []string{"read","write","writeraw"}
+			accessTypes = []string{"read", "write", "writeraw"}
 		} else {
-			accessTypes = []string{"read","write"}
+			accessTypes = []string{"read", "write"}
 		}
 	} else {
-		accessTypes,err = authorizeByToken(creds)
+		accessTypes, err = authorizeByToken(creds)
 	}
 
-	return accessTypes,err
+	return accessTypes, err
 }
 
 func authorize(request authorizationRequest, creds SourceCredentials) (common.BeamtimeMeta, error) {
@@ -306,42 +320,70 @@ func authorize(request authorizationRequest, creds SourceCredentials) (common.Be
 	}
 
 	meta.AccessTypes = accessTypes
-	log.Debug("authorized creds bl/bt: ", creds.Beamline+"/"+creds.BeamtimeId+", beamtime " + meta.BeamtimeId + " for " + request.OriginHost + " in " +
-		meta.Beamline+", type "+meta.Type, "online path "+meta.OnlinePath + ", offline path "+meta.OfflinePath)
+	log.Debug("authorized creds bl/bt: ", creds.Beamline+"/"+creds.BeamtimeId+", beamtime "+meta.BeamtimeId+" for "+request.OriginHost+" in "+
+		meta.Beamline+", type "+meta.Type, "online path "+meta.OnlinePath+", offline path "+meta.OfflinePath)
 	return meta, nil
 }
 
+func writeServerError(w http.ResponseWriter, err error) {
+	serr, ok := err.(*common.ServerError)
+	if ok {
+		utils.WriteServerError(w, err, serr.Code)
+		return
+	}
+	utils.WriteServerError(w, err, http.StatusUnauthorized)
+	return
+}
+
 func routeAuthorize(w http.ResponseWriter, r *http.Request) {
 	var request authorizationRequest
-	err := utils.ExtractRequest(r,&request)
+	err := utils.ExtractRequest(r, &request)
 	if err != nil {
-		utils.WriteServerError(w,err,http.StatusBadRequest)
+		utils.WriteServerError(w, err, http.StatusBadRequest)
 		return
 	}
 
 	creds, err := getSourceCredentials(request)
 	if err != nil {
-		utils.WriteServerError(w,err,http.StatusBadRequest)
+		utils.WriteServerError(w, err, http.StatusBadRequest)
 		return
 	}
 
 	beamtimeInfo, err := authorize(request, creds)
-	if (err != nil) {
-		serr,ok:=err.(*common.ServerError)
-		if ok {
-			utils.WriteServerError(w,err,serr.Code)
-			return
-		}
-		utils.WriteServerError(w,err,http.StatusUnauthorized)
+	if err != nil {
+		writeServerError(w, err)
 		return
 	}
 
 	res, err := utils.MapToJson(&beamtimeInfo)
 	if err != nil {
-		utils.WriteServerError(w,err,http.StatusInternalServerError)
+		utils.WriteServerError(w, err, http.StatusInternalServerError)
 		return
 	}
 
 	w.WriteHeader(http.StatusOK)
 	w.Write([]byte(res))
 }
+
+func checkRole(w http.ResponseWriter, r *http.Request, role string) error {
+	var extraClaim structs.AccessTokenExtraClaim
+	var claims *utils.CustomClaims
+	if err := utils.JobClaimFromContext(r, &claims, &extraClaim); err != nil {
+		w.WriteHeader(http.StatusInternalServerError)
+		w.Write([]byte(err.Error()))
+		return err
+	}
+
+	if err := checkTokenRevoked(claims.Id); err != nil {
+		writeServerError(w, err)
+		return err
+	}
+
+	if claims.Subject != "admin" || !utils.StringInSlice(role, extraClaim.AccessTypes) {
+		err_txt := "wrong token claims"
+		w.WriteHeader(http.StatusUnauthorized)
+		w.Write([]byte(err_txt))
+		return errors.New(err_txt)
+	}
+	return nil
+}
diff --git a/authorizer/src/asapo_authorizer/server/authorize_test.go b/authorizer/src/asapo_authorizer/server/authorize_test.go
index 7272ea101c0c1fed437ca450580779fbd016333d..3f7781e04b10f406046d5565d9f4f274b2f3aa0c 100644
--- a/authorizer/src/asapo_authorizer/server/authorize_test.go
+++ b/authorizer/src/asapo_authorizer/server/authorize_test.go
@@ -4,6 +4,7 @@ import (
 	"asapo_authorizer/authorization"
 	"asapo_authorizer/common"
 	"asapo_authorizer/ldap_client"
+	"asapo_authorizer/token_store"
 	"asapo_common/structs"
 	"asapo_common/utils"
 	"github.com/stretchr/testify/assert"
@@ -16,20 +17,22 @@ import (
 	"testing"
 )
 
+var expectedTokenId = "123"
 
-func prepareAsapoToken(payload string, accessTypes []string) string{
-	auth := authorization.NewAuth(nil,utils.NewJWTAuth("secret_user"),nil)
+func prepareAsapoToken(payload string, accessTypes []string) string {
+	auth := authorization.NewAuth(nil, utils.NewJWTAuth("secret_user"), nil)
 	var claims utils.CustomClaims
 	var extraClaim structs.AccessTokenExtraClaim
 	claims.Subject = payload
+	claims.Id = expectedTokenId
 	extraClaim.AccessTypes = accessTypes
 	claims.ExtraClaims = &extraClaim
 	token, _ := auth.AdminAuth().GenerateToken(&claims)
 	return token
 }
 
-func prepareAdminToken(payload string) string{
-	auth:= authorization.NewAuth(nil,utils.NewJWTAuth("secret_admin"),nil)
+func prepareAdminToken(payload string) string {
+	auth := authorization.NewAuth(nil, utils.NewJWTAuth("secret_admin"), nil)
 
 	var claims utils.CustomClaims
 	var extraClaim structs.AccessTokenExtraClaim
@@ -42,7 +45,6 @@ func prepareAdminToken(payload string) string{
 
 var mockClient = new(ldap_client.MockedLdapClient)
 
-
 type request struct {
 	path    string
 	cmd     string
@@ -51,10 +53,9 @@ type request struct {
 }
 
 func allowBeamlines(beamlines []common.BeamtimeMeta) {
-	common.Settings.AlwaysAllowedBeamtimes=beamlines
+	common.Settings.AlwaysAllowedBeamtimes = beamlines
 }
 
-
 func containsMatcher(substr string) func(str string) bool {
 	return func(str string) bool { return strings.Contains(str, substr) }
 }
@@ -64,56 +65,56 @@ func makeRequest(request interface{}) string {
 	return string(buf)
 }
 
-func doPostRequest(path string,buf string,authHeader string) *httptest.ResponseRecorder {
+func doPostRequest(path string, buf string, authHeader string) *httptest.ResponseRecorder {
 	mux := utils.NewRouter(listRoutes)
 	req, _ := http.NewRequest("POST", path, strings.NewReader(buf))
-	if authHeader!="" {
-		req.Header.Add("Authorization",authHeader)
+	if authHeader != "" {
+		req.Header.Add("Authorization", authHeader)
 	}
 	w := httptest.NewRecorder()
 	mux.ServeHTTP(w, req)
 	return w
 }
 
-var credTests = [] struct {
+var credTests = []struct {
 	request string
-	cred SourceCredentials
-	ok bool
+	cred    SourceCredentials
+	ok      bool
 	message string
-} {
-	{"processed%asapo_test%auto%%", SourceCredentials{"asapo_test","auto","detector","","processed"},true,"auto beamline, source and no token"},
-	{"processed%asapo_test%auto%%token", SourceCredentials{"asapo_test","auto","detector","token","processed"},true,"auto beamline, source"},
-	{"processed%asapo_test%auto%source%", SourceCredentials{"asapo_test","auto","source","","processed"},true,"auto beamline, no token"},
-	{"processed%asapo_test%auto%source%token", SourceCredentials{"asapo_test","auto","source","token","processed"},true,"auto beamline,source, token"},
-	{"processed%asapo_test%beamline%source%token", SourceCredentials{"asapo_test","beamline","source","token","processed"},true,"all set"},
-	{"processed%auto%beamline%source%token", SourceCredentials{"auto","beamline","source","token","processed"},true,"auto beamtime"},
-	{"raw%auto%auto%source%token", SourceCredentials{},false,"auto beamtime and beamline"},
-	{"raw%%beamline%source%token", SourceCredentials{"auto","beamline","source","token","raw"},true,"empty beamtime"},
-	{"raw%asapo_test%%source%token", SourceCredentials{"asapo_test","auto","source","token","raw"},true,"empty bealine"},
-	{"raw%%%source%token", SourceCredentials{},false,"both empty"},
-	{"processed%asapo_test%beamline%source%blabla%token", SourceCredentials{"asapo_test","beamline","source%blabla","token","processed"},true,"% in source"},
-	{"processed%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test","beamline","source%blabla","","processed"},true,"% in source, no token"},
+}{
+	{"processed%asapo_test%auto%%", SourceCredentials{"asapo_test", "auto", "detector", "", "processed"}, true, "auto beamline, source and no token"},
+	{"processed%asapo_test%auto%%token", SourceCredentials{"asapo_test", "auto", "detector", "token", "processed"}, true, "auto beamline, source"},
+	{"processed%asapo_test%auto%source%", SourceCredentials{"asapo_test", "auto", "source", "", "processed"}, true, "auto beamline, no token"},
+	{"processed%asapo_test%auto%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "processed"}, true, "auto beamline,source, token"},
+	{"processed%asapo_test%beamline%source%token", SourceCredentials{"asapo_test", "beamline", "source", "token", "processed"}, true, "all set"},
+	{"processed%auto%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "processed"}, true, "auto beamtime"},
+	{"raw%auto%auto%source%token", SourceCredentials{}, false, "auto beamtime and beamline"},
+	{"raw%%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "raw"}, true, "empty beamtime"},
+	{"raw%asapo_test%%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "raw"}, true, "empty bealine"},
+	{"raw%%%source%token", SourceCredentials{}, false, "both empty"},
+	{"processed%asapo_test%beamline%source%blabla%token", SourceCredentials{"asapo_test", "beamline", "source%blabla", "token", "processed"}, true, "% in source"},
+	{"processed%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed"}, true, "% in source, no token"},
 }
 
 func TestSplitCreds(t *testing.T) {
 
 	for _, test := range credTests {
-		request :=  authorizationRequest{test.request,"host"}
-		creds,err := getSourceCredentials(request)
+		request := authorizationRequest{test.request, "host"}
+		creds, err := getSourceCredentials(request)
 		if test.ok {
-			assert.Nil(t,err)
-			assert.Equal(t,test.cred,creds,test.message)
+			assert.Nil(t, err)
+			assert.Equal(t, test.cred, creds, test.message)
 		} else {
-			assert.NotNil(t,err,test.message)
+			assert.NotNil(t, err, test.message)
 		}
 
 	}
 }
 
 func TestAuthorizeDefaultOK(t *testing.T) {
-	allowBeamlines([]common.BeamtimeMeta{{"asapo_test","beamline","","2019","tf","",nil}})
-	request :=  makeRequest(authorizationRequest{"processed%asapo_test%%%","host"})
-	w := doPostRequest("/authorize",request,"")
+	allowBeamlines([]common.BeamtimeMeta{{"asapo_test", "beamline", "", "2019", "tf", "", nil}})
+	request := makeRequest(authorizationRequest{"processed%asapo_test%%%", "host"})
+	w := doPostRequest("/authorize", request, "")
 
 	body, _ := ioutil.ReadAll(w.Body)
 
@@ -125,7 +126,7 @@ func TestAuthorizeDefaultOK(t *testing.T) {
 	assert.Equal(t, http.StatusOK, w.Code, "")
 }
 
-var beamtime_meta_online =`
+var beamtime_meta_online = `
 {
 "beamline": "bl1",
 "beamtimeId": "test_online",
@@ -133,7 +134,7 @@ var beamtime_meta_online =`
 }
 `
 
-var beamtime_meta =`
+var beamtime_meta = `
 {
 "applicant": {
 "email": "test",
@@ -172,7 +173,7 @@ var beamtime_meta =`
 }
 `
 
-var commissioning_meta =`
+var commissioning_meta = `
 {
     "beamline": "P04",
     "corePath": "/asap3/petra3/gpfs/p04/2021/commissioning/c20210823_000_MAA",
@@ -182,76 +183,80 @@ var commissioning_meta =`
 }
 `
 
-
-var authTests = [] struct {
+var authTests = []struct {
 	source_type string
 	beamtime_id string
-	beamline string
-	dataSource string
-	token string
-	originHost string
-	status int
-	message string
-	answer string
+	beamline    string
+	dataSource  string
+	token       string
+	originHost  string
+	status      int
+	message     string
+	answer      string
+	mode        int
 }{
-	{"processed","test","auto","dataSource", prepareAsapoToken("bt_test",nil),"127.0.0.2",http.StatusUnauthorized,"missing access types",
-		""},
-	{"processed","test","auto","dataSource", prepareAsapoToken("bt_test",[]string{}),"127.0.0.2",http.StatusUnauthorized,"empty access types",
-		""},
-	{"processed","test","auto","dataSource", prepareAsapoToken("bt_test",[]string{"write"}),"127.0.0.2",http.StatusOK,"user source with correct token",
-		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["write"]}`},
-	{"processed","test_online","auto","dataSource", prepareAsapoToken("bt_test_online",[]string{"read"}),"127.0.0.1",http.StatusOK,"with online path, processed type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed","access-types":["read"]}`},
-	{"processed","test1","auto","dataSource", prepareAsapoToken("bt_test1",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"correct token, beamtime not found",
-		""},
-	{"processed","test","auto","dataSource", prepareAsapoToken("wrong",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"user source with wrong token",
-		""},
-	{"processed","test","bl1","dataSource", prepareAsapoToken("bt_test",[]string{"read"}),"127.0.0.1",http.StatusOK,"correct beamline given",
-		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read"]}`},
-		{"processed","test","bl2","dataSource", prepareAsapoToken("bt_test",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"incorrect beamline given",
-		""},
-	{"processed","auto","p07", "dataSource", prepareAsapoToken("bl_p07",[]string{"read"}),"127.0.0.1",http.StatusOK,"beamtime found",
-		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed","access-types":["read"]}`},
-	{"processed","auto","p07", "dataSource", prepareAsapoToken("bl_p06",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"wrong token",
-		""},
-	{"processed","auto","p08", "dataSource", prepareAsapoToken("bl_p08",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"beamtime not found",
-		""},
-	{"raw","test_online","auto","dataSource", "","127.0.0.1",http.StatusOK,"raw type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`},
-	{"raw","test_online","auto","dataSource", "","127.0.0.1",http.StatusOK,"raw type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`},
- 	{"raw","auto","p07","dataSource", "","127.0.0.1",http.StatusOK,"raw type, auto beamtime",
-		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","write","writeraw"]}`},
-	{"raw","auto","p07","noldap", "","127.0.0.1",http.StatusNotFound,"no conection to ldap",
-		""},
-
-	{"raw","auto","p07","dataSource", prepareAsapoToken("bl_p07",[]string{"read","writeraw"}),"127.0.0.2",http.StatusOK,"raw type with token",
-		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","writeraw"]}`},
-
-	{"raw","test_online","auto","dataSource", "","127.0.0.2",http.StatusUnauthorized,"raw type, wrong origin host",
-		""},
-	{"raw","test","auto","dataSource", prepareAsapoToken("bt_test",[]string{"read"}),"127.0.0.1",http.StatusUnauthorized,"raw when not online",
-		""},
-	{"processed","test","auto","dataSource", "","127.0.0.1:1001",http.StatusOK,"processed without token",
-		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read","write"]}`},
-	{"processed","test","auto","dataSource", "","127.0.0.2",http.StatusUnauthorized,"processed without token, wrong host",
-		""},
-	{"raw","c20210823_000_MAA","auto","dataSource", "","127.0.0.1",http.StatusOK,"raw type commissioning",
-		`{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"./p04/commissioning","source-type":"raw","access-types":["read","write","writeraw"]}`},
-	{"processed","c20210823_000_MAA","auto","dataSource", "","127.0.0.1",http.StatusOK,"processed type commissioning",
-		`{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"","source-type":"processed","access-types":["read","write"]}`},
+	{"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", nil), "127.0.0.2", http.StatusUnauthorized, "missing access types",
+		"", 0},
+	{"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{}), "127.0.0.2", http.StatusUnauthorized, "empty access types",
+		"", 0},
+	{"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusOK, "user source with correct token",
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["write"]}`, 0},
+	{"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusUnauthorized, "token was revoked",
+		"", 2},
+	{"processed", "test_online", "auto", "dataSource", prepareAsapoToken("bt_test_online", []string{"read"}), "127.0.0.1", http.StatusOK, "with online path, processed type",
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0},
+	{"processed", "test1", "auto", "dataSource", prepareAsapoToken("bt_test1", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "correct token, beamtime not found",
+		"", 1},
+	{"processed", "test", "auto", "dataSource", prepareAsapoToken("wrong", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "user source with wrong token",
+		"", 0},
+	{"processed", "test", "bl1", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusOK, "correct beamline given",
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0},
+	{"processed", "test", "bl2", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "incorrect beamline given",
+		"", 1},
+	{"processed", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read"}), "127.0.0.1", http.StatusOK, "beamtime found",
+		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0},
+	{"processed", "auto", "p07", "dataSource", prepareAsapoToken("bl_p06", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "wrong token",
+		"", 0},
+	{"processed", "auto", "p08", "dataSource", prepareAsapoToken("bl_p08", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "beamtime not found",
+		"", 1},
+	{"raw", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type",
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0},
+	{"raw", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type",
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0},
+	{"raw", "auto", "p07", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type, auto beamtime",
+		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0},
+	{"raw", "auto", "p07", "noldap", "", "127.0.0.1", http.StatusNotFound, "no conection to ldap",
+		"", 0},
+
+	{"raw", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read", "writeraw"}), "127.0.0.2", http.StatusOK, "raw type with token",
+		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","writeraw"]}`, 0},
+
+	{"raw", "test_online", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "raw type, wrong origin host",
+		"", 0},
+	{"raw", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "raw when not online",
+		"", 1},
+	{"processed", "test", "auto", "dataSource", "", "127.0.0.1:1001", http.StatusOK, "processed without token",
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read","write"]}`, 0},
+	{"processed", "test", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "processed without token, wrong host",
+		"", 0},
+	{"raw", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type commissioning",
+		`{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"./p04/commissioning","source-type":"raw","access-types":["read","write","writeraw"]}`, 0},
+	{"processed", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "processed type commissioning",
+		`{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"","source-type":"processed","access-types":["read","write"]}`, 0},
 }
 
 func TestAuthorize(t *testing.T) {
 	ldapClient = mockClient
 	allowBeamlines([]common.BeamtimeMeta{})
-	Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret"))
+	Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"), utils.NewJWTAuth("secret_admin"), utils.NewJWTAuth("secret"))
+	mock_store := new(token_store.MockedStore)
+	store = mock_store
 	expected_uri := "expected_uri"
 	expected_base := "expected_base"
 	allowed_ips := []string{"127.0.0.1"}
-	common.Settings.RootBeamtimesFolder ="."
-	common.Settings.CurrentBeamlinesFolder="."
-	common.Settings.Ldap.FilterTemplate="a3__BEAMLINE__-hosts"
+	common.Settings.RootBeamtimesFolder = "."
+	common.Settings.CurrentBeamlinesFolder = "."
+	common.Settings.Ldap.FilterTemplate = "a3__BEAMLINE__-hosts"
 	common.Settings.Ldap.Uri = expected_uri
 	common.Settings.Ldap.BaseDn = expected_base
 
@@ -266,109 +271,118 @@ func TestAuthorize(t *testing.T) {
 	ioutil.WriteFile(filepath.Clean("bl1/current/beamtime-metadata-test_online.json"), []byte(beamtime_meta_online), 0644)
 	ioutil.WriteFile(filepath.Clean("p04/commissioning/commissioning-metadata-c20210823_000_MAA.json"), []byte(commissioning_meta), 0644)
 
-	defer 	os.RemoveAll("p07")
-	defer 	os.RemoveAll("p04")
-	defer 	os.RemoveAll("tf")
-	defer 	os.RemoveAll("bl1")
+	defer os.RemoveAll("p07")
+	defer os.RemoveAll("p04")
+	defer os.RemoveAll("tf")
+	defer os.RemoveAll("bl1")
 
 	for _, test := range authTests {
-		if test.source_type == "raw" || test.token == "" {bl := test.beamline
+		if test.token != "" && test.mode != 1 {
+			if test.mode == 2 {
+				mock_store.On("IsTokenRevoked", expectedTokenId).Return(true, nil)
+			} else {
+				mock_store.On("IsTokenRevoked", expectedTokenId).Return(false, nil)
+			}
+		}
+
+		if test.source_type == "raw" || test.token == "" {
+			bl := test.beamline
 			if test.beamline == "auto" {
 				bl = "bl1"
 			}
-			if iscommissioning(test.beamtime_id)  && test.beamline == "auto" {
+			if iscommissioning(test.beamtime_id) && test.beamline == "auto" {
 				bl = "p04"
 			}
-			expected_filter:="a3"+bl+"-hosts"
+			expected_filter := "a3" + bl + "-hosts"
 			if test.dataSource == "noldap" {
-				err := &common.ServerError{utils.StatusServiceUnavailable,""}
-				mockClient.On("GetAllowedIpsForBeamline", expected_uri, expected_base,expected_filter).Return([]string{}, err)
+				err := &common.ServerError{utils.StatusServiceUnavailable, ""}
+				mockClient.On("GetAllowedIpsForBeamline", expected_uri, expected_base, expected_filter).Return([]string{}, err)
 			} else {
-				mockClient.On("GetAllowedIpsForBeamline", expected_uri, expected_base,expected_filter).Return(allowed_ips, nil)
+				mockClient.On("GetAllowedIpsForBeamline", expected_uri, expected_base, expected_filter).Return(allowed_ips, nil)
 			}
 		}
 
-		request :=  makeRequest(authorizationRequest{test.source_type+"%"+test.beamtime_id+"%"+test.beamline+"%"+test.dataSource+"%"+test.token,test.originHost})
-		w := doPostRequest("/authorize",request,"")
+		request := makeRequest(authorizationRequest{test.source_type + "%" + test.beamtime_id + "%" + test.beamline + "%" + test.dataSource + "%" + test.token, test.originHost})
+		w := doPostRequest("/authorize", request, "")
 
 		body, _ := ioutil.ReadAll(w.Body)
-		if test.status==http.StatusOK {
-			body_str:=string(body)
-			body_str = strings.Replace(body_str,string(os.PathSeparator),"/",-1)
-			body_str = strings.Replace(body_str,"//","/",-1)
-			assert.Equal(t, test.answer,body_str,test.message)
+		if test.status == http.StatusOK {
+			body_str := string(body)
+			body_str = strings.Replace(body_str, string(os.PathSeparator), "/", -1)
+			body_str = strings.Replace(body_str, "//", "/", -1)
+			assert.Equal(t, test.answer, body_str, test.message)
 		}
-		assert.Equal(t, test.status,w.Code, test.message)
+		assert.Equal(t, test.status, w.Code, test.message)
 		mockClient.AssertExpectations(t)
-		mockClient.ExpectedCalls=nil
+		mockClient.ExpectedCalls = nil
+		mock_store.AssertExpectations(t)
+		mock_store.ExpectedCalls = nil
+		mock_store.Calls = nil
 	}
 }
 
 func TestNotAuthorized(t *testing.T) {
-	request :=  makeRequest(authorizationRequest{"raw%any_id%%%","host"})
-	w := doPostRequest("/authorize",request,"")
+	request := makeRequest(authorizationRequest{"raw%any_id%%%", "host"})
+	w := doPostRequest("/authorize", request, "")
 	assert.Equal(t, http.StatusUnauthorized, w.Code, "")
 }
 
-
 func TestAuthorizeWrongRequest(t *testing.T) {
-	w := doPostRequest("/authorize","babla","")
+	w := doPostRequest("/authorize", "babla", "")
 	assert.Equal(t, http.StatusBadRequest, w.Code, "")
 }
 
-
 func TestAuthorizeWrongPath(t *testing.T) {
-	w := doPostRequest("/authorized","","")
+	w := doPostRequest("/authorized", "", "")
 	assert.Equal(t, http.StatusNotFound, w.Code, "")
 }
 
 func TestDoNotAuthorizeIfNotInAllowed(t *testing.T) {
-	allowBeamlines([]common.BeamtimeMeta{{"test","beamline","","2019","tf","",nil}})
+	allowBeamlines([]common.BeamtimeMeta{{"test", "beamline", "", "2019", "tf", "", nil}})
 
-	request :=  authorizationRequest{"asapo_test%%","host"}
-	creds,_ := getSourceCredentials(request)
-	_,err := authorize(request,creds)
-	assert.Error(t,err, "")
+	request := authorizationRequest{"asapo_test%%", "host"}
+	creds, _ := getSourceCredentials(request)
+	_, err := authorize(request, creds)
+	assert.Error(t, err, "")
 }
 
 func TestSplitHost(t *testing.T) {
 	host := splitHost("127.0.0.1:112")
-	assert.Equal(t,"127.0.0.1", host, "")
+	assert.Equal(t, "127.0.0.1", host, "")
 }
 
-
 func TestSplitHostNoPort(t *testing.T) {
 	host := splitHost("127.0.0.1")
-	assert.Equal(t,"127.0.0.1", host, "")
+	assert.Equal(t, "127.0.0.1", host, "")
 }
 
-var extractBtinfoTests = [] struct {
-	root string
-	fname string
+var extractBtinfoTests = []struct {
+	root     string
+	fname    string
 	beamline string
-	id string
-	ok bool
+	id       string
+	ok       bool
 }{
-	{".",filepath.Clean("tf/gpfs/bl1.01/2019/data/123"),"bl1.01","123",true},
-	{filepath.Clean("/blabla/tratartra"),filepath.Clean("tf/gpfs/bl1.01/2019/data/123"), "bl1.01","123",true},
-	{".",filepath.Clean("tf/gpfs/common/2019/data/123"), "bl1.01","123",false},
-	{".",filepath.Clean("tf/gpfs/BeamtimeUsers/2019/data/123"), "bl1.01","123",false},
-	{".",filepath.Clean("tf/gpfs/state/2019/data/123"), "bl1.01","123",false},
-	{".",filepath.Clean("tf/gpfs/support/2019/data/123"), "bl1.01","123",false},
-	{".",filepath.Clean("petra3/gpfs/p01/2019/commissioning/c20180508-000-COM20181"), "p01","c20180508-000-COM20181",true},
-
+	{".", filepath.Clean("tf/gpfs/bl1.01/2019/data/123"), "bl1.01", "123", true},
+	{filepath.Clean("/blabla/tratartra"), filepath.Clean("tf/gpfs/bl1.01/2019/data/123"), "bl1.01", "123", true},
+	{".", filepath.Clean("tf/gpfs/common/2019/data/123"), "bl1.01", "123", false},
+	{".", filepath.Clean("tf/gpfs/BeamtimeUsers/2019/data/123"), "bl1.01", "123", false},
+	{".", filepath.Clean("tf/gpfs/state/2019/data/123"), "bl1.01", "123", false},
+	{".", filepath.Clean("tf/gpfs/support/2019/data/123"), "bl1.01", "123", false},
+	{".", filepath.Clean("petra3/gpfs/p01/2019/commissioning/c20180508-000-COM20181"), "p01", "c20180508-000-COM20181", true},
 }
+
 func TestGetBeamtimeInfo(t *testing.T) {
 	for _, test := range extractBtinfoTests {
-		common.Settings.RootBeamtimesFolder=test.root
-		bt,err:= beamtimeMetaFromMatch(test.root+string(filepath.Separator)+test.fname)
+		common.Settings.RootBeamtimesFolder = test.root
+		bt, err := beamtimeMetaFromMatch(test.root + string(filepath.Separator) + test.fname)
 		if test.ok {
-			assert.Equal(t,bt.OfflinePath,test.root+string(filepath.Separator)+test.fname)
-			assert.Equal(t,bt.Beamline,test.beamline)
-			assert.Equal(t,bt.BeamtimeId,test.id)
-			assert.Nil(t,err,"should not be error")
+			assert.Equal(t, bt.OfflinePath, test.root+string(filepath.Separator)+test.fname)
+			assert.Equal(t, bt.Beamline, test.beamline)
+			assert.Equal(t, bt.BeamtimeId, test.id)
+			assert.Nil(t, err, "should not be error")
 		} else {
-			assert.NotNil(t,err,"should be error")
+			assert.NotNil(t, err, "should be error")
 		}
 	}
 
diff --git a/authorizer/src/asapo_authorizer/server/folder_token_test.go b/authorizer/src/asapo_authorizer/server/folder_token_test.go
index 88c02cba5f960ab017e1508157ff30ce3d6b355f..ae39cee67b223f2d4d04da60cd749d240af877f7 100644
--- a/authorizer/src/asapo_authorizer/server/folder_token_test.go
+++ b/authorizer/src/asapo_authorizer/server/folder_token_test.go
@@ -3,11 +3,13 @@ package server
 import (
 	"asapo_authorizer/authorization"
 	"asapo_authorizer/common"
+	"asapo_authorizer/token_store"
 	"asapo_common/structs"
 	"asapo_common/utils"
 	"asapo_common/version"
 	"fmt"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
 	"io/ioutil"
 	"net/http"
 	"os"
@@ -39,6 +41,9 @@ var  fodlerTokenTests = [] struct {
 
 func TestFolderToken(t *testing.T) {
 	allowBeamlines([]common.BeamtimeMeta{})
+	mock_store := new(token_store.MockedStore)
+	store = mock_store
+
 	common.Settings.RootBeamtimesFolder ="."
 	common.Settings.CurrentBeamlinesFolder="."
 	Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret_folder"))
@@ -65,6 +70,8 @@ func TestFolderToken(t *testing.T) {
 		request :=  makeRequest(folderTokenRequest{path_in_token,test.beamtime_id,test.token})
 		if test.status == http.StatusBadRequest {
 			request =makeRequest(authorizationRequest{})
+		} else {
+			mock_store.On("IsTokenRevoked", mock.Anything).Return(false, nil)
 		}
 		w := doPostRequest("/"+version.GetAuthorizerApiVersion()+"/folder",request,"")
 		if w.Code == http.StatusOK {
@@ -78,7 +85,9 @@ func TestFolderToken(t *testing.T) {
 			body, _ := ioutil.ReadAll(w.Body)
 			fmt.Println(string(body))
 		}
-
+		mock_store.AssertExpectations(t)
+		mock_store.ExpectedCalls = nil
+		mock_store.Calls = nil
 		assert.Equal(t, test.status, w.Code, test.message)
 	}
 }
diff --git a/authorizer/src/asapo_authorizer/server/introspect.go b/authorizer/src/asapo_authorizer/server/introspect.go
index b846e395dcb677175d0e02aaaacb85395280a287..5dd591a2c37f274e552cba63aab7e60829b5431b 100644
--- a/authorizer/src/asapo_authorizer/server/introspect.go
+++ b/authorizer/src/asapo_authorizer/server/introspect.go
@@ -23,6 +23,11 @@ func verifyUserToken(token string) (response structs.IntrospectTokenResponse, er
 	if err!=nil {
 		return
 	}
+	err = checkTokenRevoked(claim.Id)
+	if err != nil {
+		return
+	}
+
 	response.Sub = claim.Subject
 	response.AccessTypes = extra_claim.AccessTypes
 	return
diff --git a/authorizer/src/asapo_authorizer/server/introspect_test.go b/authorizer/src/asapo_authorizer/server/introspect_test.go
index 9a42bc066a09c5bf2db9da2f65563aff5a0004b2..40a99b52fe531d720cb902feccc577202b472709 100644
--- a/authorizer/src/asapo_authorizer/server/introspect_test.go
+++ b/authorizer/src/asapo_authorizer/server/introspect_test.go
@@ -2,6 +2,7 @@ package server
 
 import (
 	"asapo_authorizer/authorization"
+	"asapo_authorizer/token_store"
 	"asapo_common/structs"
 	"asapo_common/utils"
 	"encoding/json"
@@ -27,11 +28,16 @@ func TestIntrospect(t *testing.T) {
 	authJWT := utils.NewJWTAuth("secret")
 	authAdmin := utils.NewJWTAuth("secret_admin")
 	authUser := utils.NewJWTAuth("secret_user")
+	mock_store := new(token_store.MockedStore)
+	store = mock_store
+
 	Auth = authorization.NewAuth(authUser,authAdmin,authJWT)
 	for _, test := range IntrospectTests {
 		token := prepareAsapoToken(test.tokenSubject,test.roles)
 		if test.status==http.StatusUnauthorized {
 			token = "blabla"
+		} else {
+			mock_store.On("IsTokenRevoked", expectedTokenId).Return(false, nil)
 		}
 		request :=  makeRequest(structs.IntrospectTokenRequest{token})
 		w := doPostRequest("/introspect",request,"")
@@ -46,6 +52,9 @@ func TestIntrospect(t *testing.T) {
 			body, _ := ioutil.ReadAll(w.Body)
 			fmt.Println(string(body))
 		}
+		mock_store.AssertExpectations(t)
+		mock_store.ExpectedCalls = nil
+		mock_store.Calls = nil
 	}
 }
 
diff --git a/authorizer/src/asapo_authorizer/server/issue_token.go b/authorizer/src/asapo_authorizer/server/issue_token.go
index 8b9bae25305b864af8d00f434ea3e5d47c40fb25..bf2524abf9317081b2dd22f063cc1cf05d1774a9 100644
--- a/authorizer/src/asapo_authorizer/server/issue_token.go
+++ b/authorizer/src/asapo_authorizer/server/issue_token.go
@@ -2,11 +2,13 @@ package server
 
 import (
 	"asapo_authorizer/authorization"
+	"asapo_authorizer/token_store"
 	log "asapo_common/logger"
 	"asapo_common/structs"
 	"asapo_common/utils"
 	"errors"
 	"net/http"
+	"time"
 )
 
 func extractUserTokenrequest(r *http.Request) (request structs.IssueTokenRequest, err error) {
@@ -37,19 +39,12 @@ func extractUserTokenrequest(r *http.Request) (request structs.IssueTokenRequest
 }
 
 func routeAuthorisedTokenIssue(w http.ResponseWriter, r *http.Request) {
-	Auth.AdminAuth().ProcessAuth(checkAccessToken, "admin")(w, r)
+	Auth.AdminAuth().ProcessAuth(checkAccessToken, "")(w, r)
 }
+
 func checkAccessToken(w http.ResponseWriter, r *http.Request) {
-	var extraClaim structs.AccessTokenExtraClaim
-	var claims *utils.CustomClaims
-	if err := utils.JobClaimFromContext(r, &claims, &extraClaim); err != nil {
-		w.WriteHeader(http.StatusInternalServerError)
-		w.Write([]byte(err.Error()))
-	}
-	if claims.Subject != "admin" || !utils.StringInSlice("create",extraClaim.AccessTypes) {
-		err_txt := "wrong token claims"
-		w.WriteHeader(http.StatusUnauthorized)
-		w.Write([]byte(err_txt))
+	if checkRole(w, r, "create") != nil {
+		return
 	}
 
 	issueUserToken(w, r)
@@ -62,12 +57,22 @@ func issueUserToken(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	token, _, err := Auth.PrepareAccessToken(request, true)
+	token, claims, err := Auth.PrepareAccessToken(request, true)
 	if err != nil {
 		utils.WriteServerError(w, err, http.StatusInternalServerError)
 		return
 	}
 
+	claims.StandardClaims.Issuer = "asapo-auth"
+	claims.StandardClaims.IssuedAt = time.Now().Unix()
+	record := token_store.TokenRecord{claims.Id, claims, token, false}
+	err = store.AddToken(record)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusInternalServerError)
+		return
+	}
+
+
 	log.Debug("generated user token ")
 
 	answer := authorization.UserTokenResponce(request, token)
diff --git a/authorizer/src/asapo_authorizer/server/issue_token_test.go b/authorizer/src/asapo_authorizer/server/issue_token_test.go
index ee267ca90e6b0e349a7eb033bbfa096bcdf7f2bf..a36552063691c66572e98f276d1fd6550e2d7e00 100644
--- a/authorizer/src/asapo_authorizer/server/issue_token_test.go
+++ b/authorizer/src/asapo_authorizer/server/issue_token_test.go
@@ -2,11 +2,13 @@ package server
 
 import (
 	"asapo_authorizer/authorization"
+	"asapo_authorizer/token_store"
 	"asapo_common/structs"
 	"asapo_common/utils"
 	"encoding/json"
 	"fmt"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
 	"io/ioutil"
 	"net/http"
 	"testing"
@@ -40,8 +42,15 @@ func TestIssueToken(t *testing.T) {
 	authAdmin := utils.NewJWTAuth("secret_admin")
 	authUser := utils.NewJWTAuth("secret_user")
 	Auth = authorization.NewAuth(authUser,authAdmin,authJWT)
+	mock_store := new(token_store.MockedStore)
+	store = mock_store
+
 	for _, test := range IssueTokenTests {
 		request :=  makeRequest(structs.IssueTokenRequest{test.requestSubject,test.validDays,test.roles})
+		mock_store.On("IsTokenRevoked", mock.Anything).Return(false,nil)
+		if test.status == http.StatusOK {
+			mock_store.On("AddToken", mock.Anything).Return(nil)
+		}
 		w := doPostRequest("/admin/issue",request,authAdmin.Name()+" "+test.adminToken)
 		if w.Code == http.StatusOK {
 			body, _ := ioutil.ReadAll(w.Body)
@@ -60,6 +69,9 @@ func TestIssueToken(t *testing.T) {
 			body, _ := ioutil.ReadAll(w.Body)
 			fmt.Println(string(body))
 		}
+		mock_store.AssertExpectations(t)
+		mock_store.ExpectedCalls = nil
+		mock_store.Calls = nil
 
 		assert.Equal(t, test.status, w.Code, test.message)
 	}
diff --git a/authorizer/src/asapo_authorizer/server/listroutes.go b/authorizer/src/asapo_authorizer/server/listroutes.go
index 09b695091ffc4ecf686715a5b7a4f10434280cbb..d1f027f0aa048b2a0a3e41c9340694e99a11effb 100644
--- a/authorizer/src/asapo_authorizer/server/listroutes.go
+++ b/authorizer/src/asapo_authorizer/server/listroutes.go
@@ -17,6 +17,12 @@ var listRoutes = utils.Routes{
 		"/introspect",
 		routeIntrospect,
 	},
+	utils.Route{
+		"Authorize",
+		"POST",
+		"/admin/revoke",
+		routeRevoke,
+	},
 	utils.Route{
 		"HealthCheck",
 		"Get",
diff --git a/authorizer/src/asapo_authorizer/server/revoke_token.go b/authorizer/src/asapo_authorizer/server/revoke_token.go
new file mode 100644
index 0000000000000000000000000000000000000000..c1c98c6f2adf4c3a3fe05fd94b5773352861b75c
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/server/revoke_token.go
@@ -0,0 +1,39 @@
+package server
+
+import (
+	log "asapo_common/logger"
+	"asapo_common/utils"
+	"encoding/json"
+	"net/http"
+)
+
+func routeRevoke(w http.ResponseWriter, r *http.Request) {
+	Auth.AdminAuth().ProcessAuth(processRevoke, "")(w, r)
+}
+
+func processRevoke(w http.ResponseWriter, r *http.Request) {
+	if checkRole(w, r, "revoke") != nil {
+		return
+	}
+	revokeToken(w, r)
+}
+
+func revokeToken(w http.ResponseWriter, r *http.Request) {
+	token, err := extractToken(r)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusBadRequest)
+		return
+	}
+
+	rec, err := store.RevokeToken(token, "")
+	if err != nil {
+		log.Error("could not revoke token "+ token+": "+ err.Error())
+		utils.WriteServerError(w, err, http.StatusBadRequest)
+		return
+	}
+
+	log.Debug("revoked token " + rec.Token)
+	answer, _ := json.Marshal(&rec)
+	w.WriteHeader(http.StatusOK)
+	w.Write(answer)
+}
diff --git a/authorizer/src/asapo_authorizer/token_store/mock_store.go b/authorizer/src/asapo_authorizer/token_store/mock_store.go
index b2db86bcbbf8bf0363310e0c75487631a2ff76d4..7d0a35923d098701ad1fb329de1c2d85db944b70 100644
--- a/authorizer/src/asapo_authorizer/token_store/mock_store.go
+++ b/authorizer/src/asapo_authorizer/token_store/mock_store.go
@@ -30,9 +30,9 @@ func (store *MockedStore)  GetTokenList() ([]TokenRecord,error) {
 	return args.Get(0).([]TokenRecord), args.Error(1)
 }
 
-func (store *MockedStore) GetRevokedTokenIds() ([]string,error) {
-	args := store.Called()
-	return args.Get(0).([]string), args.Error(1)
+func (store *MockedStore)  IsTokenRevoked(tokenId string) (bool, error) {
+	args := store.Called(tokenId)
+	return args.Get(0).(bool), args.Error(1)
 }
 
 func (store *MockedStore) Close() {
diff --git a/authorizer/src/asapo_authorizer/token_store/token_store.go b/authorizer/src/asapo_authorizer/token_store/token_store.go
index 0de0d1c45c61a240079f478673ff3b829ce25774..756d7cc2d970292697c0b2fd4ecd0fcebcd909a9 100644
--- a/authorizer/src/asapo_authorizer/token_store/token_store.go
+++ b/authorizer/src/asapo_authorizer/token_store/token_store.go
@@ -16,7 +16,7 @@ type Store interface {
 	AddToken(token TokenRecord) error
 	RevokeToken(token string, id string) (TokenRecord, error)
 	GetTokenList() ([]TokenRecord, error)
-	GetRevokedTokenIds() ([]string, error)
+	IsTokenRevoked(tokenId string) (bool, error)
 	Close()
 }
 
@@ -133,16 +133,6 @@ func (store *TokenStore) updateTokenStatus(token *TokenRecord) error {
 		Collection: KTokens,
 		Op:         "update_record",
 	}, token.Id, map[string]interface{}{"revoked": true}, false, token)
-	if err != nil {
-		return err
-	}
-
-	idRec := IdRecord{token.Id}
-	_, err = store.db.ProcessRequest(Request{
-		DbName:     KAdminDb,
-		Collection: KRevokedTokens,
-		Op:         "create_record",
-	}, &idRec)
 	return err
 }
 
@@ -172,6 +162,9 @@ func (store *TokenStore) RevokeToken(token string, id string) (TokenRecord, erro
 		return TokenRecord{}, store.processError(err)
 	}
 
+	store.revokedTokenList.lock.Lock()
+	defer store.revokedTokenList.lock.Unlock()
+	store.revokedTokenList.tokens = append(store.revokedTokenList.tokens, tokenRecord.Id)
 	return tokenRecord, nil
 }
 
@@ -197,6 +190,7 @@ func (store *TokenStore) loopGetRevokedTokens() {
 		if err != nil {
 			store.revokedTokenList.lock.Lock()
 			store.revokedTokenList.lastError = err
+			store.revokedTokenList.tokens = nil
 			store.processError(err)
 			store.revokedTokenList.lock.Unlock()
 			next_update = 1
@@ -209,6 +203,7 @@ func (store *TokenStore) loopGetRevokedTokens() {
 				tokens[i] = token.Id
 			}
 			store.revokedTokenList.lock.Lock()
+			store.revokedTokenList.lastError = nil
 			store.revokedTokenList.tokens = tokens
 			store.revokedTokenList.lock.Unlock()
 		}
@@ -221,15 +216,23 @@ func (store *TokenStore) loopGetRevokedTokens() {
 	}
 }
 
-func (store *TokenStore) GetRevokedTokenIds() ([]string, error) {
+func (store *TokenStore) IsTokenRevoked(tokenId string) (bool, error) {
+	tokens, err := store.getRevokedTokenIds()
+	if err != nil {
+		return true, err
+	}
+	return utils.StringInSlice(tokenId, tokens), nil
+}
+
+func (store *TokenStore) getRevokedTokenIds() ([]string, error) {
 	store.revokedTokenList.lock.RLock()
 	defer store.revokedTokenList.lock.RUnlock()
 	if store.revokedTokenList.lastError != nil {
 		return []string{}, store.revokedTokenList.lastError
 	}
-//	res := make([]string, len(store.revokedTokenList.tokens))
-//	copy(res, store.revokedTokenList.tokens)
-//	return res,nil
+	//	res := make([]string, len(store.revokedTokenList.tokens))
+	//	copy(res, store.revokedTokenList.tokens)
+	//	return res,nil
 	return store.revokedTokenList.tokens, nil
 }
 
diff --git a/authorizer/src/asapo_authorizer/token_store/token_store_test.go b/authorizer/src/asapo_authorizer/token_store/token_store_test.go
index 550784d6364b95e3369a5a2de3f75661e3059e71..d648f0ef3afbcf9d259237f425a3ca7ccc85e449 100644
--- a/authorizer/src/asapo_authorizer/token_store/token_store_test.go
+++ b/authorizer/src/asapo_authorizer/token_store/token_store_test.go
@@ -127,7 +127,7 @@ func (suite *TokenStoreTestSuite) TestProcessRequestRevokeToken() {
 	suite.Equal(token, expectedRevokedToken, "ok")
 }
 
-func (suite *TokenStoreTestSuite) TestProcessRequestGetRevokedTokens() {
+func (suite *TokenStoreTestSuite) TestProcessRequestCheckRevokedToken() {
 	suite.mock_db.On("Close")
 	suite.store.Close()
 	common.Settings.UpdateRevokedTokensIntervalSec = 5
@@ -141,6 +141,7 @@ func (suite *TokenStoreTestSuite) TestProcessRequestGetRevokedTokens() {
 
 	logger.MockLog.On("Debug", mock.MatchedBy(containsMatcher("list")))
 	time.Sleep(time.Second*1)
-	_,err := suite.store.GetRevokedTokenIds()
+	res,err := suite.store.IsTokenRevoked("123")
 	suite.Equal(err, nil, "ok")
+	suite.Equal(false, res, "ok")
 }
\ No newline at end of file
diff --git a/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json b/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
index b6c3d5534036a419d0ba4ae7462bb569c00c7030..db3745ac6dfe47362541d0413508dd13714ef655 100644
--- a/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
+++ b/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
@@ -14,5 +14,6 @@
   "Uri" : "ldap://localhost:389",
   "BaseDn" : "ou=rgy,o=desy,c=de",
   "FilterTemplate" : "(cn=a3__BEAMLINE__-hosts)"
-  }
+  },
+  "UpdateRevokedTokensIntervalSec": 60
 }
diff --git a/deploy/asapo_services/scripts/authorizer.json.tpl b/deploy/asapo_services/scripts/authorizer.json.tpl
index d5c24a2bb6c55fae2f5defe21a5d0577c7d08810..1d77de613c0a03883370bb4812b92b83f22d89b9 100644
--- a/deploy/asapo_services/scripts/authorizer.json.tpl
+++ b/deploy/asapo_services/scripts/authorizer.json.tpl
@@ -16,5 +16,6 @@
         "FilterTemplate" : "(cn=a3__BEAMLINE__-hosts)"
     },
   "DatabaseServer":"auto",
-  "DiscoveryServer": "localhost:8400/asapo-discovery"
+  "DiscoveryServer": "localhost:8400/asapo-discovery",
+  "UpdateRevokedTokensIntervalSec": 60
 }
diff --git a/tests/automatic/authorizer/check_authorize/check_linux.sh b/tests/automatic/authorizer/check_authorize/check_linux.sh
index d881c72aac94e6fb5a9b3635b699332e026e9d40..340c715bce4db2135a33d2015d171d6599d921c6 100644
--- a/tests/automatic/authorizer/check_authorize/check_linux.sh
+++ b/tests/automatic/authorizer/check_authorize/check_linux.sh
@@ -6,6 +6,7 @@ trap Cleanup EXIT
 
 Cleanup() {
 	echo cleanup
+  echo "db.dropDatabase()" | mongo asapo_admin
 }
 
 mkdir -p /tmp/asapo/asap3/petra3/gpfs/p00/2019/comissioning/c20180508-000-COM20181
@@ -20,8 +21,10 @@ cp beamtime-metadata-11111112.json /tmp/asapo/beamline/p08/current/
 AdminToken=$ASAPO_CREATE_TOKEN
 echo admin $AdminToken
 
-curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr -  | tee /dev/stderr | grep "bt_12345678"
-curl -v --silent -H "Authorization: Bearer blabla" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr -  | tee /dev/stderr | grep "token does not match"
+RevokeToken=$ASAPO_REVOKE_TOKEN
+
+curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr -  | tee /dev/stderr | grep "bt_12345678"
+curl -v --silent -H "Authorization: Bearer blabla" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr -  | tee /dev/stderr | grep "token does not match"
 
 curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr -  | tee /dev/stderr  | grep c20180508-000-COM20181
 curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr -  | tee /dev/stderr  | grep p00
@@ -59,4 +62,18 @@ curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$t
 token=$BLP07_W_TOKEN
 curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr -  | tee /dev/stderr  | grep write
 
+
+#revocation
+token=`curl --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"11000015"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue | jq -r .Token`
+echo $token
+
+curl -v --silent --data "{\"SourceCredentials\":\"processed%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr -  | tee /dev/stderr  | grep p00
+
+#revoke token
+curl -v --silent -H "Authorization: Bearer $RevokeToken" --data '{"Token": "'"$token"'"}' 127.0.0.1:8400/asapo-authorizer/admin/revoke | grep '"Revoked":true'
+
+sleep 1
+
+curl -v --silent --data "{\"SourceCredentials\":\"processed%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr -  | tee /dev/stderr  | grep 401
+
 rm -rf /tmp/asapo/asap3 /tmp/asapo/beamline
\ No newline at end of file
diff --git a/tests/automatic/settings/authorizer_settings.json.tpl.lin b/tests/automatic/settings/authorizer_settings.json.tpl.lin
index 1de8b3d3b3342a6c2a363e2fa9221c93d6df030f..dd30b9d3c0a6f7361f55b2a700cd39b37e5b3b67 100644
--- a/tests/automatic/settings/authorizer_settings.json.tpl.lin
+++ b/tests/automatic/settings/authorizer_settings.json.tpl.lin
@@ -17,5 +17,6 @@
      "FilterTemplate" : "(cn=a3__BEAMLINE__-hosts)"
   },
   "DatabaseServer":"auto",
-  "DiscoveryServer": "localhost:8400/asapo-discovery"
+  "DiscoveryServer": "localhost:8400/asapo-discovery",
+  "UpdateRevokedTokensIntervalSec": 60
 }
diff --git a/tests/automatic/settings/authorizer_settings.json.tpl.win b/tests/automatic/settings/authorizer_settings.json.tpl.win
index cbf7535bc0974c0353b198b9c089e2b259fee203..dff507941808259b140f48ad9ec816b643c57bb5 100644
--- a/tests/automatic/settings/authorizer_settings.json.tpl.win
+++ b/tests/automatic/settings/authorizer_settings.json.tpl.win
@@ -17,5 +17,6 @@
      "FilterTemplate" : "(cn=a3__BEAMLINE__-hosts)"
   },
   "DatabaseServer":"auto",
-  "DiscoveryServer": "localhost:8400/asapo-discovery"
+  "DiscoveryServer": "localhost:8400/asapo-discovery",
+  "UpdateRevokedTokensIntervalSec": 60
 }