diff --git a/CHANGELOG.md b/CHANGELOG.md
index cef299dc9d92ce07b865a6c46e8b75a1fd8af536..a26180846d0335d7dd3b4f09f651def6b38b25f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,12 @@
 ## 21.03.0 (in progress)
 
  IMPROVEMENTS
+<<<<<<< HEAD
 * Producer API - queue limits in Python, for C++ return original data in error custom data      
 * Consumer API - add GetCurrentDatasetCount/get_current_dataset_count function with option to include or exclude incomplete datasets
 * Consumer API - GetStreamList/get_stream_list - can filter finished/unfinished streams now
 * Producer/Consumer API - StreamInfo structure/Python dictionary include more information (is stream finished or not, ...) 
+* Switch to JWT tokens (token has more symbols, expiration time, can be revoked and there are two type of tokens - with read/write access rights)
 
 BREAKING CHANGES
 * Consumer API (C++ only)- GetStreamList has now extra argument StreamFilter
diff --git a/CMakeModules/coverage_go.sh b/CMakeModules/coverage_go.sh
index 13ddb7a413da1f36d24fd24021a75760a25bc082..5b01cf48bb047093f0605fb0b115751c1aa38be4 100755
--- a/CMakeModules/coverage_go.sh
+++ b/CMakeModules/coverage_go.sh
@@ -4,8 +4,6 @@ SOURCE_DIR=$1
 OUT_DIR=$2
 ASAPO_MINIMUM_COVERAGE=$3
 
-export GOPATH=$GOPATH:$4
-
 echo $OUT_DIR
 
 touch $OUT_DIR/coverage.out
diff --git a/CMakeModules/prepare_asapo.cmake b/CMakeModules/prepare_asapo.cmake
index 0c5baa12c4bf1815588ba447d22fe4fe78a51d2a..7ef66d96fc259d1a812691f43e245a7d2205164f 100644
--- a/CMakeModules/prepare_asapo.cmake
+++ b/CMakeModules/prepare_asapo.cmake
@@ -50,6 +50,8 @@ function(prepare_asapo)
     configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json.tpl broker.json.tpl COPYONLY)
     configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/file_transfer_settings.json.tpl file_transfer.json.tpl COPYONLY)
     configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
+    configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/admin_token.key admin_token.key COPYONLY)
+    configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret_admin.key auth_secret_admin.key COPYONLY)
     configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/nginx.conf.tpl nginx.conf.tpl COPYONLY)
     configure_file(${CMAKE_SOURCE_DIR}/config/nomad/nginx.nmd.in nginx.nmd @ONLY)
 
diff --git a/CMakeModules/testing_go.cmake b/CMakeModules/testing_go.cmake
index dbba4bfe2bde4687bc416bf0da08314b87e613d3..f130ab796ec0d94aeebffc94252ba628ea55b4aa 100644
--- a/CMakeModules/testing_go.cmake
+++ b/CMakeModules/testing_go.cmake
@@ -13,11 +13,6 @@ function(gotest target source_dir test_source_files)
     if (BUILD_TESTS)
                 add_test(NAME test-${target} COMMAND go test ${test_source_files}
                 WORKING_DIRECTORY ${source_dir})
-        set_property(
-                TEST
-                test-${target}
-                PROPERTY
-                ENVIRONMENT "GOPATH=${gopath}")
         message(STATUS "Added test 'test-${target}'")
         if (CMAKE_COMPILER_IS_GNUCXX)
         add_test(NAME coveragetest-${target}
@@ -29,16 +24,11 @@ function(gotest target source_dir test_source_files)
     endif ()
 endfunction()
 
-function(go_integration_test target test_source_files label)
+function(go_integration_test target source_dir test_source_files label)
     if (BUILD_TESTS)
         add_test(NAME test-${target} COMMAND go test ${test_source_files} -run ${label}
                 -tags integration_tests
-                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-        set_property(
-                TEST
-                test-${target}
-                PROPERTY
-                ENVIRONMENT "GOPATH=${gopath}")
+                WORKING_DIRECTORY ${source_dir})
         message(STATUS "Added test 'test-${target}'")
     endif ()
 endfunction()
diff --git a/asapo_tools/CMakeLists.txt b/asapo_tools/CMakeLists.txt
index 48cf94c7b756447465c55884be6c8ebd2bbe8f5e..4ac248cce955ad6ced89a510d9962111ef15ce37 100644
--- a/asapo_tools/CMakeLists.txt
+++ b/asapo_tools/CMakeLists.txt
@@ -1,20 +1,8 @@
 set (TARGET_NAME asapo)
 
-if (NOT "$ENV{GOPATH}" STREQUAL "")
-	set(GOPATH $ENV{GOPATH})
-endif()
-
-if (NOT GOPATH)
-    message (FATAL_ERROR "GOPATH not set")
-endif()
-
-message(STATUS "global gopath ${GOPATH}")
-
 IF(WIN32)
-    set (gopath "${GOPATH}\;${CMAKE_CURRENT_SOURCE_DIR}\;${CMAKE_SOURCE_DIR}/common/go")
     set (exe_name "${TARGET_NAME}.exe")
 ELSE()
-    set (gopath ${GOPATH}:${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_SOURCE_DIR}/common/go)
     set (exe_name "${TARGET_NAME}")
 #    set (GO_OPTS "GOOS=linux;CGO_ENABLED=0")
 ENDIF()
@@ -22,13 +10,13 @@ ENDIF()
 include(testing_go)
 
 add_custom_target(asapo ALL
-    COMMAND  ${CMAKE_COMMAND} -E env GOPATH=${gopath}
-        ${GO_OPTS} go build -o ${exe_name} asapo_tools/main
-    VERBATIM)
+    COMMAND  go build ${GO_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} main/asapo.go
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_tools
+        VERBATIM)
 define_property(TARGET PROPERTY EXENAME
         BRIEF_DOCS <executable name>
         FULL_DOCS <full-doc>)
 
 set_target_properties(${TARGET_NAME} PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name})
 
-gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}" "./...")
+gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_tools" "./...")
diff --git a/asapo_tools/src/asapo_tools/cli/command.go b/asapo_tools/src/asapo_tools/cli/command.go
index b61171a1a94dc23e97eebd89f41d7d8bd635198b..24f3bb619fa185f32ef84bb5dc5ee1aa954bf6d4 100644
--- a/asapo_tools/src/asapo_tools/cli/command.go
+++ b/asapo_tools/src/asapo_tools/cli/command.go
@@ -1,7 +1,6 @@
 package cli
 
 import (
-	"errors"
 	"flag"
 	"fmt"
 )
@@ -21,10 +20,6 @@ func (cmd *command) description(d string) bool {
 	return false
 }
 
-func (cmd *command) errBadOptions(err string) error {
-	return errors.New("asapo " + cmd.name + ": " + err + "\nType 'asapo " + cmd.name + " --help'")
-}
-
 // createDefaultFlagset creates new flagset and adds default help behaviour.
 func (cmd *command) createDefaultFlagset(description, args string) *flag.FlagSet {
 
diff --git a/asapo_tools/src/asapo_tools/cli/command_test.go b/asapo_tools/src/asapo_tools/cli/command_test.go
index c4e89f2239f69728ba190d4db6d7aa59011550b0..358090965eccc2ecf6d506963eb592589024f995 100644
--- a/asapo_tools/src/asapo_tools/cli/command_test.go
+++ b/asapo_tools/src/asapo_tools/cli/command_test.go
@@ -10,7 +10,7 @@ var CommandTests = []struct {
 	cmd    command
 	answer string
 }{
-	{command{"token", []string{"-secret", "secret_file", "beamtime"}}, "secret"},
+	{command{"token", []string{"-secret", "secret_file","-type","read","-endpoint","bla", "beamtime"}}, "secret"},
 	{command{"dummy", []string{"description"}}, "wrong"},
 }
 
@@ -22,7 +22,6 @@ func TestCommand(t *testing.T) {
 		err := DoCommand(test.cmd.name, test.cmd.args)
 		assert.Contains(t, err.Error(), test.answer, "")
 		assert.NotNil(t, err, "Should be error")
-
 	}
 
 }
diff --git a/asapo_tools/src/asapo_tools/cli/token.go b/asapo_tools/src/asapo_tools/cli/token.go
index cc68a114f10690966116d9ce74c7b73386bd9e69..d3567b38ab22447842454fc336dde2681624669b 100644
--- a/asapo_tools/src/asapo_tools/cli/token.go
+++ b/asapo_tools/src/asapo_tools/cli/token.go
@@ -1,29 +1,38 @@
 package cli
 
 import (
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"asapo_tools/rest_client"
+	"bytes"
+	"encoding/json"
 	"errors"
-	"os"
 	"fmt"
-	"asapo_common/utils"
+	"io"
+	"net/http"
+	"os"
 )
 
 type tokenFlags struct {
-	Name       string
-	SecretFile string
+	Name         string
+	Endpoint     string
+	AccessType   string
+	SecretFile   string
+	TokenDetails bool
 }
 
-func generateToken(id string,secret string) string {
-	hmac := utils.NewHMACAuth(secret)
-	token,err := hmac.GenerateToken(&id)
+func generateToken(flags tokenFlags, secret string) string {
+	//	hmac := utils.NewHMACAuth(secret)
+	//	token,err := hmac.GenerateToken(&id)
 
-	if (err!=nil) {
-		fmt.Println(err.Error())
-	}
-	return token
+	//	if (err!=nil) {
+	//		fmt.Println(err.Error())
+	//	}
+	//	return token
+	return ""
 }
 
-
-// GenerateToken generates token for consumers
+// CommandToken receives token from authorization server
 func (cmd *command) CommandToken() error {
 
 	message_string := "Generate token"
@@ -38,21 +47,62 @@ func (cmd *command) CommandToken() error {
 	}
 
 	secret, err := utils.ReadFirstStringFromFile(flags.SecretFile)
-	if err !=nil  {
+	if err != nil {
 		return err
 	}
 
-	fmt.Fprintf(outBuf, "%s\n", generateToken(flags.Name,secret))
+	request := structs.IssueTokenRequest{
+		Subject:    map[string]string{"beamtimeId": flags.Name},
+		DaysValid:  180,
+		AccessType: flags.AccessType,
+	}
+	json_data, _ := json.Marshal(request)
+	path := flags.Endpoint + "/admin/issue"
 
-	return nil
-}
+	req, err := http.NewRequest("POST", path, bytes.NewBuffer(json_data))
+	if err != nil {
+		return err
+	}
+	req.Header.Add("Content-Type", "application/json")
+	req.Header.Add("Authorization", "Bearer "+secret)
 
+	resp, err := rest_client.Client.Do(req)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return err
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return errors.New("returned " + resp.Status + ": " + string(body))
+	}
+
+	if flags.TokenDetails {
+		fmt.Fprintf(outBuf, "%s\n", string(body))
+		return nil
+	}
+
+	var token structs.IssueTokenResponse
+
+	err = json.Unmarshal(body, &token)
+	if err == nil {
+		fmt.Fprintf(outBuf, "%s\n", token.Token)
+	}
+	return err
+}
 
 func (cmd *command) parseTokenFlags(message_string string) (tokenFlags, error) {
 
 	var flags tokenFlags
 	flagset := cmd.createDefaultFlagset(message_string, "<token_body>")
 	flagset.StringVar(&flags.SecretFile, "secret", "", "path to file with secret")
+	flagset.StringVar(&flags.AccessType, "type", "", "access type")
+	flagset.StringVar(&flags.Endpoint, "endpoint", "", "asapo endpoint")
+	flagset.BoolVar(&flags.TokenDetails, "token-details", false, "output token details")
 
 	flagset.Parse(cmd.args)
 
@@ -63,13 +113,20 @@ func (cmd *command) parseTokenFlags(message_string string) (tokenFlags, error) {
 	flags.Name = flagset.Arg(0)
 
 	if flags.Name == "" {
-		return flags, errors.New("beamtime id or beamline missed ")
+		return flags, errors.New("payload missed ")
 	}
 
 	if flags.SecretFile == "" {
 		return flags, errors.New("secret file missed ")
 	}
 
+	if flags.Endpoint == "" {
+		return flags, errors.New("endpoint missed ")
+	}
+
+	if flags.AccessType != "read" && flags.AccessType != "write" {
+		return flags, errors.New("incorrect or missed token access type ")
+	}
 
 	return flags, nil
 
diff --git a/asapo_tools/src/asapo_tools/cli/token_test.go b/asapo_tools/src/asapo_tools/cli/token_test.go
index 4d443f3c493f86aceb6156e5638aeb2f802a71bb..c1b54b2961f7227f0623f23f497aa8c134569478 100644
--- a/asapo_tools/src/asapo_tools/cli/token_test.go
+++ b/asapo_tools/src/asapo_tools/cli/token_test.go
@@ -1,35 +1,69 @@
 package cli
 
 import (
+	"asapo_tools/mocks"
+	"asapo_tools/rest_client"
+	"encoding/json"
+	"net/http"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
 	"bytes"
+	"github.com/stretchr/testify/assert"
 	"io/ioutil"
 	"os"
 )
 
 var tokenTests = []struct {
 	cmd      command
-	answer string
+	withDetails bool
+	ok bool
 	msg  string
 }{
-	{command{args: []string{"beamtime_id"}},  "secret", "no secret parameter"},
-	{command{args: []string{"-secret","secret.tmp"}},  "beamtime id", "no file"},
-	{command{args: []string{"-secret","not_existing_file","beamtime_id"}},  "not_existing_file", "no file"},
-	{command{args: []string{"-secret","secret.tmp","beamtime_id"}},  "eodk3s5ZXwACLGyVA63MZYcOTWuWE4bceI9Vxl9zejI=", "no file"},
+	{command{args: []string{"beamtime_id"}},  false,false, "no secret parameter"},
+	{command{args: []string{"-secret","secret.tmp"}},  false,false, "no file"},
+	{command{args: []string{"-secret","not_existing_file","payload"}}, false, false, "no file"},
+	{command{args: []string{"-secret","secret.tmp","beamtime_id"}},false,  false, "type is missing"},
+	{command{args: []string{"-secret","secret.tmp","-type","read","beamtime_id"}}, false, false, "endpoint is missing"},
+	{command{args: []string{"-secret","secret.tmp","-type","read","-endpoint","endpoint","-token-details","beamtime_id"}},true,  true, "ok"},
+	{command{args: []string{"-secret","secret.tmp","-type","read","-endpoint","endpoint","beamtime_id"}},  false,true, "without details"},
 }
 
 func TestParseTokenFlags(t *testing.T) {
 
 	ioutil.WriteFile("secret.tmp", []byte("secret"), 0644)
-	outBuf = new(bytes.Buffer)
+
+	rest_client.Client = &mocks.MockClient{}
+
+
+	mocks.DoFunc = func(req *http.Request) (*http.Response, error) {
+		json := `{"Token":"blabla","Uri":"`+req.URL.Path+`"}`
+		r := ioutil.NopCloser(bytes.NewReader([]byte(json)))
+
+		return &http.Response{
+			StatusCode: 200,
+			Body:       r,
+		}, nil
+	}
+
 	for _, test := range tokenTests {
+		outBuf = new(bytes.Buffer)
 		err := test.cmd.CommandToken()
-		if err == nil {
-			assert.Contains(t, outBuf.(*bytes.Buffer).String(), test.answer, test.msg)
+		if test.ok {
+			assert.Nil(t, err, test.msg)
+			resp := struct {
+				Token string
+				Uri string
+			}{}
+			if test.withDetails {
+				err := json.Unmarshal(outBuf.(*bytes.Buffer).Bytes(),&resp)
+				assert.Nil(t, err, test.msg)
+				assert.Equal(t,  "blabla", resp.Token,test.msg)
+				assert.Equal(t, "endpoint/admin/issue",resp.Uri, test.msg)
+			} else {
+				assert.Equal(t,  "blabla\n", outBuf.(*bytes.Buffer).String(),test.msg)
+			}
 		} else {
-			assert.Contains(t, err.Error(), test.answer, test.msg)
+			assert.NotNil(t, err, test.msg)
 		}
 
 	}
diff --git a/asapo_tools/src/asapo_tools/go.mod b/asapo_tools/src/asapo_tools/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..85df870aee982144559bdda3bbaac0daa4b034b3
--- /dev/null
+++ b/asapo_tools/src/asapo_tools/go.mod
@@ -0,0 +1,12 @@
+module asapo_tools
+
+go 1.16
+
+replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common
+
+require (
+	asapo_common v0.0.0
+	github.com/kr/pretty v0.2.0 // indirect
+	github.com/stretchr/testify v1.7.0
+	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
+)
diff --git a/asapo_tools/src/asapo_tools/go.sum b/asapo_tools/src/asapo_tools/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..3e9dd5cbe821c458765373bc58e66d087906c706
--- /dev/null
+++ b/asapo_tools/src/asapo_tools/go.sum
@@ -0,0 +1,26 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/asapo_tools/src/asapo_tools/main/asapo.go b/asapo_tools/src/asapo_tools/main/asapo.go
index 66d5829ec67bd6b966a938b7940b3119505e9539..256dedcac06e54ee1289b56b66b631ab4fd16197 100644
--- a/asapo_tools/src/asapo_tools/main/asapo.go
+++ b/asapo_tools/src/asapo_tools/main/asapo.go
@@ -1,8 +1,10 @@
 package main
 
 import (
+	"asapo_tools/rest_client"
 	"flag"
 	"fmt"
+	"net/http"
 	"os"
 	"asapo_common/version"
 	"asapo_tools/cli"
@@ -20,6 +22,8 @@ func main() {
 
 	flag.Parse()
 
+	rest_client.Client = &http.Client{}
+
 	if *flHelp || flag.NArg() == 0 {
 		flag.Usage()
 		cli.PrintAllCommands()
diff --git a/asapo_tools/src/asapo_tools/mocks/mock_client.go b/asapo_tools/src/asapo_tools/mocks/mock_client.go
new file mode 100644
index 0000000000000000000000000000000000000000..0cf47f5ffa267a21ae472c614d4c8b01f15c81d7
--- /dev/null
+++ b/asapo_tools/src/asapo_tools/mocks/mock_client.go
@@ -0,0 +1,13 @@
+package mocks
+
+import "net/http"
+
+type MockClient struct {
+	DoFunc func(req *http.Request) (*http.Response, error)
+}
+
+func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
+	return DoFunc(req)
+}
+
+var DoFunc func(req *http.Request) (*http.Response, error)
diff --git a/asapo_tools/src/asapo_tools/rest_client/rest_client.go b/asapo_tools/src/asapo_tools/rest_client/rest_client.go
new file mode 100644
index 0000000000000000000000000000000000000000..b303b59380056723d9a3d404d73c392edd8767dd
--- /dev/null
+++ b/asapo_tools/src/asapo_tools/rest_client/rest_client.go
@@ -0,0 +1,9 @@
+package rest_client
+
+import "net/http"
+
+type HTTPClient interface {
+	Do(req *http.Request) (*http.Response, error)
+}
+
+var Client HTTPClient
diff --git a/authorizer/CMakeLists.txt b/authorizer/CMakeLists.txt
index a48ac016d99a5f032de55f5f5a271bafe7aee03f..cc8384833523a807b0acb8c5b904c81003df3ffe 100644
--- a/authorizer/CMakeLists.txt
+++ b/authorizer/CMakeLists.txt
@@ -1,20 +1,8 @@
 set (TARGET_NAME asapo-authorizer)
 
-if (NOT "$ENV{GOPATH}" STREQUAL "")
-	set(GOPATH $ENV{GOPATH})
-endif()
-
-if (NOT GOPATH)
-    message (FATAL_ERROR "GOPATH not set")
-endif()
-
-message(STATUS "global gopath ${GOPATH}")
-
 IF(WIN32)
-    set (gopath "${GOPATH}\;${CMAKE_CURRENT_SOURCE_DIR}\;${CMAKE_SOURCE_DIR}/common/go")
     set (exe_name "${TARGET_NAME}.exe")
 ELSE()
-    set (gopath ${GOPATH}:${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_SOURCE_DIR}/common/go)
     set (exe_name "${TARGET_NAME}")
 ENDIF()
 
@@ -23,8 +11,8 @@ include(testing_go)
 configure_file(docker/Dockerfile . COPYONLY)
 
 add_custom_target(asapo-authorizer ALL
-    COMMAND  ${CMAKE_COMMAND} -E env GOPATH=${gopath}
-    go build ${GO_OPTS} -o ${exe_name} asapo_authorizer/main
+    COMMAND go build ${GO_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} main/authorizer.go
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_authorizer
     VERBATIM)
 define_property(TARGET PROPERTY EXENAME
         BRIEF_DOCS <executable name>
@@ -32,6 +20,4 @@ define_property(TARGET PROPERTY EXENAME
 
 set_target_properties(asapo-authorizer PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name})
 
-gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}" "./...")
-#go_integration_test(${TARGET_NAME}-connectdb "./..." "MongoDBConnect")
-#go_integration_test(${TARGET_NAME}-nextrecord "./..." "MongoDBNext")
+gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_authorizer" "./...")
diff --git a/authorizer/src/asapo_authorizer/authorization/authorization.go b/authorizer/src/asapo_authorizer/authorization/authorization.go
new file mode 100644
index 0000000000000000000000000000000000000000..6d15baab442dde0acaf39e1a4c7cc75400cc9d23
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/authorization/authorization.go
@@ -0,0 +1,79 @@
+package authorization
+
+import (
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"encoding/json"
+	"github.com/rs/xid"
+	"time"
+)
+
+type Auth struct {
+	authUser  utils.Auth
+	authAdmin utils.Auth
+	authJWT   utils.Auth
+}
+
+func NewAuth(authUser,authAdmin,authJWT utils.Auth) *Auth {
+	return &Auth{authUser,authAdmin,authJWT}
+}
+
+func (auth *Auth) AdminAuth() utils.Auth {
+	return auth.authAdmin
+}
+
+func (auth *Auth) UserAuth() utils.Auth {
+	return auth.authUser
+}
+
+func (auth *Auth) JWTAuth() utils.Auth {
+	return auth.authJWT
+}
+
+func subjectFromRequest(request structs.IssueTokenRequest) string {
+	for key,value := range request.Subject {
+		switch key {
+		case "beamline":
+			return utils.SubjectFromBeamline(value)
+		case "beamtimeId":
+			return utils.SubjectFromBeamtime(value)
+		default:
+			return value
+		}
+	}
+	return ""
+}
+
+func (auth *Auth) PrepareAccessToken(request structs.IssueTokenRequest, userToken bool) (string, error) {
+	var claims utils.CustomClaims
+	var extraClaim structs.AccessTokenExtraClaim
+
+	claims.Subject = subjectFromRequest(request)
+
+	extraClaim.AccessType = request.AccessType
+	claims.ExtraClaims = &extraClaim
+	claims.SetExpiration(time.Duration(request.DaysValid*24) * time.Hour)
+	uid := xid.New()
+	claims.Id = uid.String()
+
+	if userToken {
+		return auth.UserAuth().GenerateToken(&claims)
+	} else {
+		return auth.AdminAuth().GenerateToken(&claims)
+	}
+}
+
+func UserTokenResponce(request structs.IssueTokenRequest, token string) []byte {
+	expires := ""
+	if request.DaysValid>0 {
+		expires = time.Now().Add(time.Duration(request.DaysValid*24) * time.Hour).UTC().Format(time.RFC3339)
+	}
+	answer := structs.IssueTokenResponse{
+		Token:      token,
+		AccessType: request.AccessType,
+		Sub:  subjectFromRequest(request),
+		Expires:  expires,
+	}
+	res, _ := json.Marshal(answer)
+	return res
+}
diff --git a/authorizer/src/asapo_authorizer/cli/cli.go b/authorizer/src/asapo_authorizer/cli/cli.go
new file mode 100644
index 0000000000000000000000000000000000000000..0851d568c782b2d97f80894b3afd280f0c5a1b64
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/cli.go
@@ -0,0 +1,60 @@
+// Package contains asapo commands that can be executed from command line.
+// Every CommandXxxx function that is a member of a cmd struct processes asapo xxxx command
+package cli
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"strings"
+)
+
+var flHelp bool
+
+var outBuf io.Writer = os.Stdout
+
+func printHelp(f *flag.FlagSet) bool {
+	if flHelp {
+		f.Usage()
+		return true
+	} else {
+		return false
+	}
+}
+
+// DoCommand takes command name as a parameter and executes corresponding to this name cmd method
+func DoCommand(name string, args []string) error {
+	commandName := "Command" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
+	cmd := new(command)
+	commandName = strings.ReplaceAll(commandName,"-","_")
+	methodVal := reflect.ValueOf(cmd).MethodByName(commandName)
+	if !methodVal.IsValid() {
+		return errors.New("wrong "+ProgramName+" command: " + name + "\nType '"+os.Args[0]+" -help'")
+	}
+	cmd.name = strings.ReplaceAll(name,"-","_")
+	cmd.args = args
+
+	method := methodVal.Interface().(func() error)
+
+	return method()
+}
+
+// PrintAllCommands prints all available commands (found wihtin methods of cmd)
+func PrintAllCommands() {
+	fmt.Fprintln(outBuf, "\nCommands:")
+	cmd := new(command)
+	CmdType := reflect.TypeOf(cmd)
+	for i := 0; i < CmdType.NumMethod(); i++ {
+		methodVal := CmdType.Method(i)
+		if strings.HasPrefix(methodVal.Name, "Command") {
+			method := methodVal.Func.Interface().(func(*command) error)
+			cmd.name = strings.ToLower(methodVal.Name)[7:]
+			cmd.name = strings.ReplaceAll(cmd.name,"_","-")
+			cmd.args = []string{"description"}
+			method(cmd)
+		}
+	}
+}
diff --git a/authorizer/src/asapo_authorizer/cli/command.go b/authorizer/src/asapo_authorizer/cli/command.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f8fc4f556ff1e420de679d953eab89a3c194654
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/command.go
@@ -0,0 +1,43 @@
+package cli
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"os"
+)
+
+var ProgramName string
+
+// A command consists of a command name and arguments, passed to this command (all after program name ...)
+type command struct {
+	name string
+	args []string
+}
+
+// description prints description line and returns true if first command argument is "description".
+func (cmd *command) description(d string) bool {
+	if len(cmd.args) == 1 && cmd.args[0] == "description" {
+		fmt.Fprintf(outBuf, "   %-10s %s\n", cmd.name, d)
+		return true
+	}
+	return false
+}
+
+func (cmd *command) errBadOptions(err string) error {
+	return errors.New(ProgramName + " " + cmd.name + ": " + err + "\nType '" +os.Args[0] +" " + cmd.name + " -help'")
+}
+
+// createDefaultFlagset creates new flagset and adds default help behaviour.
+func (cmd *command) createDefaultFlagset(description, args string) *flag.FlagSet {
+
+	flags := flag.NewFlagSet(cmd.name, flag.ContinueOnError)
+	flags.BoolVar(&flHelp, "help", false, "Print usage")
+	flags.Usage = func() {
+		fmt.Fprintf(outBuf, "Usage:\t\n"+ProgramName+" %s "+args, cmd.name)
+		fmt.Fprintf(outBuf, "\n\n%s\n", description)
+		flags.PrintDefaults()
+	}
+
+	return flags
+}
diff --git a/authorizer/src/asapo_authorizer/cli/command_test.go b/authorizer/src/asapo_authorizer/cli/command_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d1aad81b78e2267b69d7593eb150292083ba12e1
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/command_test.go
@@ -0,0 +1,41 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"asapo_common/utils"
+	"bytes"
+	"testing"
+	"github.com/stretchr/testify/assert"
+)
+
+var CommandTests = []struct {
+	cmd    command
+	ok bool
+	msg string
+}{
+	{command{"create-token", []string{"-type", "user-token", "-beamtime","123","-access-type","read","-duration-days","1"}}, true,"ok"},
+	{command{"dummy", []string{"description"}}, false,"wrong command"},
+}
+
+func TestCommand(t *testing.T) {
+	outBuf = new(bytes.Buffer)
+	server.Auth = authorization.NewAuth(utils.NewJWTAuth("secret"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret"))
+
+	for _, test := range CommandTests {
+		outBuf.(*bytes.Buffer).Reset()
+		err := DoCommand(test.cmd.name, test.cmd.args)
+		if !test.ok {
+			assert.NotNil(t, err, "Should be error",test.msg)
+		} else {
+			assert.Nil(t, err, "Should be ok",test.msg)
+		}
+	}
+
+}
+
+func TestPrintAllCommands(t *testing.T) {
+	outBuf = new(bytes.Buffer)
+	PrintAllCommands()
+	assert.Contains(t, outBuf.(*bytes.Buffer).String(), "token", "all commands must have token")
+}
diff --git a/authorizer/src/asapo_authorizer/cli/create_token.go b/authorizer/src/asapo_authorizer/cli/create_token.go
new file mode 100644
index 0000000000000000000000000000000000000000..a77416df704094e9646ff0b62dd90c69f4eb4c26
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/create_token.go
@@ -0,0 +1,124 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"asapo_common/structs"
+	"errors"
+	"fmt"
+	"os"
+)
+
+type tokenFlags struct {
+	Type       string
+	AccessType string
+	Beamtime   string
+	Beamline   string
+	DaysValid  int
+}
+
+func userTokenRequest(flags tokenFlags) (request structs.IssueTokenRequest, err error) {
+	if (flags.Beamline=="" && flags.Beamtime=="") || (flags.Beamline!="" && flags.Beamtime!="") {
+		return request,errors.New("beamtime or beamline must be set")
+	}
+	if flags.AccessType!="read" && flags.AccessType!="write" {
+		return request,errors.New("access type must be read of write")
+	}
+
+	request.Subject = make(map[string]string,1)
+	if (flags.Beamline!="") {
+		request.Subject["beamline"]=flags.Beamline
+	} else {
+		request.Subject["beamtimeId"]=flags.Beamtime
+	}
+	request.AccessType = flags.AccessType
+	request.DaysValid = flags.DaysValid
+
+	return
+}
+
+
+func adminTokenRequest(flags tokenFlags) (request structs.IssueTokenRequest, err error) {
+	if flags.Beamline+flags.Beamtime!="" {
+		return request,errors.New("beamtime and beamline must not be set for admin token")
+	}
+	if flags.AccessType!="create" && flags.AccessType!="revoke" && flags.AccessType!="list" {
+		return request,errors.New("access type must be create,revoke of list")
+	}
+	request.Subject = make(map[string]string,1)
+	request.Subject["user"]="admin"
+	request.AccessType = flags.AccessType
+	request.DaysValid = flags.DaysValid
+
+	return
+}
+
+func (cmd *command) CommandCreate_token() (err error) {
+	message_string := "Generate token"
+	if cmd.description(message_string) {
+		return nil
+	}
+
+	flags, err := cmd.parseTokenFlags(message_string)
+	if err != nil {
+		return err
+	}
+
+	request, userToken, err := getTokenRequest(flags)
+	if err != nil {
+		return err
+	}
+
+	token, err := server.Auth.PrepareAccessToken(request,userToken)
+	if err != nil {
+		return err
+	}
+
+	answer := authorization.UserTokenResponce(request, token)
+	fmt.Fprintf(outBuf, "%s\n", string(answer))
+	return nil
+}
+
+func getTokenRequest(flags tokenFlags) (request structs.IssueTokenRequest, userToken bool, err error) {
+	switch flags.Type {
+	case "user-token":
+		request, err = userTokenRequest(flags)
+		userToken = true
+	case "admin-token":
+		request, err = adminTokenRequest(flags)
+		userToken = false
+	default:
+		return structs.IssueTokenRequest{}, false, errors.New("wrong token type")
+	}
+	if err != nil {
+		return structs.IssueTokenRequest{},false,  err
+	}
+	return request, userToken, err
+}
+
+
+func (cmd *command) parseTokenFlags(message_string string) (tokenFlags, error) {
+
+	var flags tokenFlags
+	flagset := cmd.createDefaultFlagset(message_string, "")
+	flagset.StringVar(&flags.Type, "type", "", "token type")
+	flagset.StringVar(&flags.Beamtime, "beamtime", "", "beamtime for user token")
+	flagset.StringVar(&flags.Beamline, "beamline", "", "beamline for user token")
+	flagset.StringVar(&flags.AccessType, "access-type", "", "read/write for user token")
+	flagset.IntVar(&flags.DaysValid, "duration-days", 0, "token duration (in days)")
+
+
+	flagset.Parse(cmd.args)
+
+	if printHelp(flagset) {
+		os.Exit(0)
+	}
+
+	if flags.Type == "" {
+		return flags, errors.New("secret file missed ")
+	}
+
+
+	return flags, nil
+
+}
diff --git a/authorizer/src/asapo_authorizer/cli/create_token_test.go b/authorizer/src/asapo_authorizer/cli/create_token_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8264d6b5ec33a7ff972501c24162de82fde74369
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/create_token_test.go
@@ -0,0 +1,67 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"encoding/json"
+	"testing"
+
+	"bytes"
+	"github.com/stretchr/testify/assert"
+)
+
+var tokenTests = []struct {
+	cmd             command
+	key string
+	ok              bool
+	tokenAccessType string
+	tokenSubject    string
+	tokenExpires bool
+	msg             string
+}{
+// good
+	{command{args: []string{"-type", "user-token", "-beamtime","123","-access-type","read","-duration-days","10"}},
+		"secret_user",true, "read", "bt_123", true,"user token beamtime ok"},
+	{command{args: []string{"-type", "user-token", "-beamline","123","-access-type","read","-duration-days","10"}},
+		"secret_user",		true, "read", "bl_123", true,"user token beamline ok"},
+	{command{args: []string{"-type", "admin-token","-access-type","create"}},
+		"secret_admin",true, "create", "admin", false,"admin token ok"},
+// bad
+	{command{args: []string{"-type", "user-token", "-beamtime","123","-access-type","create","-duration-days","10"}},
+		"secret_user",false, "", "", true,"user token wrong type"},
+	{command{args: []string{"-type", "user-token", "-access-type","create","-duration-days","10"}},
+		"secret_user",false, "", "", true,"user token no beamtime or beamline"},
+	{command{args: []string{"-type", "user-token",  "-beamtime","123","-beamline","1234", "-access-type","create","-duration-days","10"}},
+		"secret_user",false, "", "", true,"user token both beamtime and beamline"},
+	{command{args: []string{"-type", "admin-token","-access-type","bla"}},
+		"secret_admin",false, "", "", false,"admin token wrong type"},
+}
+
+func TestGenerateToken(t *testing.T) {
+	server.Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret"))
+	for _, test := range tokenTests {
+		outBuf = new(bytes.Buffer)
+		err := test.cmd.CommandCreate_token()
+		if !test.ok {
+			assert.NotNil(t, err, test.msg)
+			continue
+		}
+		assert.Nil(t, err, test.msg)
+		var token structs.IssueTokenResponse
+		json.Unmarshal(outBuf.(*bytes.Buffer).Bytes(), &token)
+
+		claims,_ := utils.CheckJWTToken(token.Token,test.key)
+		cclaims,_:= claims.(*utils.CustomClaims)
+		var extra_claim structs.AccessTokenExtraClaim
+		utils.MapToStruct(cclaims.ExtraClaims.(map[string]interface{}), &extra_claim)
+		assert.Equal(t, test.tokenSubject, cclaims.Subject, test.msg)
+		assert.Equal(t, test.tokenAccessType, extra_claim.AccessType, test.msg)
+		if test.tokenExpires {
+			assert.Equal(t, true, len(token.Expires)>0, test.msg)
+		} else {
+			assert.Empty(t, token.Expires, test.msg)
+		}
+	}
+}
diff --git a/authorizer/src/asapo_authorizer/cli/daemon.go b/authorizer/src/asapo_authorizer/cli/daemon.go
new file mode 100644
index 0000000000000000000000000000000000000000..46bf9a3e7bc4bdd1cb121bd21c819f21a9749921
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/daemon.go
@@ -0,0 +1,18 @@
+package cli
+
+import (
+	"asapo_authorizer/server"
+)
+
+
+func (cmd *command) CommandDaemon() error {
+
+	message_string := "Start daemon (default)"
+	if cmd.description(message_string) {
+		return nil
+	}
+
+	server.Start()
+
+	return nil
+}
diff --git a/authorizer/src/asapo_authorizer/common/structs.go b/authorizer/src/asapo_authorizer/common/structs.go
new file mode 100644
index 0000000000000000000000000000000000000000..805d0c79aadd885ddb6ed76b1e678c10a63bbe45
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/common/structs.go
@@ -0,0 +1 @@
+package common
diff --git a/authorizer/src/asapo_authorizer/go.mod b/authorizer/src/asapo_authorizer/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..d509410645104648f2c4c28e5d7ebaafa45ee48c
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/go.mod
@@ -0,0 +1,16 @@
+module asapo_authorizer
+
+go 1.16
+
+replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common
+
+require (
+	asapo_common v0.0.0
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+	github.com/go-ldap/ldap v3.0.3+incompatible
+	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/rs/xid v1.2.1
+	github.com/sirupsen/logrus v1.8.0 // indirect
+	github.com/stretchr/testify v1.7.0
+	gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
+)
diff --git a/authorizer/src/asapo_authorizer/go.sum b/authorizer/src/asapo_authorizer/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..4e1c32df6dd6e14736ec4b0bf11f74f6a56b7ca0
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/go.sum
@@ -0,0 +1,30 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
+github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/authorizer/src/asapo_authorizer/main/authorizer.go b/authorizer/src/asapo_authorizer/main/authorizer.go
index 9f4329909333d6dac5c88966ccbc398497856941..57261418da9c80661c09aa8a5d57db7c2ea693e1 100644
--- a/authorizer/src/asapo_authorizer/main/authorizer.go
+++ b/authorizer/src/asapo_authorizer/main/authorizer.go
@@ -3,19 +3,22 @@
 package main
 
 import (
-	log "asapo_common/logger"
+	"asapo_authorizer/cli"
 	"asapo_authorizer/server"
+	log "asapo_common/logger"
 	"asapo_common/version"
 	"flag"
 	"os"
 )
 
-func PrintUsage() {
-	log.Fatal("Usage: " + os.Args[0] + " -config <config file>")
-}
+var (
+	flHelp = flag.Bool("help", false, "Print usage")
+)
 
 func main() {
-	var fname = flag.String("config", "", "config file path")
+	cli.ProgramName = "asapo-authorizer"
+
+	var fname = flag.String("config", "", "config file path (mandatory)")
 
 	if ret := version.ShowVersion(os.Stdout, "ASAPO Authorizer"); ret {
 		return
@@ -24,10 +27,16 @@ func main() {
 	log.SetSoucre("authorizer")
 
 	flag.Parse()
-	if *fname == "" {
-		PrintUsage()
+	if *flHelp {
+		flag.Usage()
+		cli.PrintAllCommands()
+		return
 	}
 
+	if *fname=="" {
+		log.Fatal("config file path is missed")
+
+	}
 	logLevel, err := server.ReadConfig(*fname)
 	if err != nil {
 		log.Fatal(err.Error())
@@ -35,5 +44,12 @@ func main() {
 
 	log.SetLevel(logLevel)
 
-	server.Start()
+	if len(flag.Args()) == 0 {
+		server.Start()
+	}
+
+	if err := cli.DoCommand(flag.Arg(0), flag.Args()[1:]); err != nil {
+		log.Fatal(err.Error())
+	}
+
 }
diff --git a/authorizer/src/asapo_authorizer/server/authorize.go b/authorizer/src/asapo_authorizer/server/authorize.go
index edcf0b703767f142d746a56235155bef6b942e91..2be720f1f85b16b262cecaa9063c2560da5fc21d 100644
--- a/authorizer/src/asapo_authorizer/server/authorize.go
+++ b/authorizer/src/asapo_authorizer/server/authorize.go
@@ -3,6 +3,7 @@ package server
 import (
 	"asapo_authorizer/common"
 	log "asapo_common/logger"
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"errors"
 	"net/http"
@@ -126,6 +127,7 @@ func alwaysAllowed(creds SourceCredentials) (beamtimeMeta, bool) {
 		if pair.BeamtimeId == creds.BeamtimeId {
 			pair.DataSource = creds.DataSource
 			pair.Type = creds.Type
+			pair.AccessType = "write"
 			return pair, true
 		}
 	}
@@ -152,26 +154,27 @@ func needHostAuthorization(creds SourceCredentials) bool {
 	return creds.Type == "raw" || len(creds.Token) == 0
 }
 
-func authorizeByToken(creds SourceCredentials) error {
-	var token_expect string
-	if (creds.BeamtimeId != "auto") {
-		token_expect, _ = authHMAC.GenerateToken(&creds.BeamtimeId)
-	} else {
-		key := "bl_" + creds.Beamline
-		token_expect, _ = authHMAC.GenerateToken(&key)
+func checkToken(token string, subject_expect string) (accessType string, err error) {
+	var extra_claim structs.AccessTokenExtraClaim
+	subject,err := Auth.UserAuth().CheckAndGetContent(token,&extra_claim)
+	if err!=nil {
+		return "",err
 	}
 
-	var err_string string
-	if creds.Token != token_expect {
-		if creds.BeamtimeId != "auto" {
-			err_string = "wrong token for beamtime " + creds.BeamtimeId
-		} else {
-			err_string = "wrong token for beamline " + creds.Beamline
-		}
-		log.Error(err_string)
-		return errors.New(err_string)
+	if subject!=subject_expect {
+		return "",errors.New("wrong token for "+subject_expect)
 	}
-	return nil
+	return extra_claim.AccessType,err
+}
+
+func authorizeByToken(creds SourceCredentials) (accessType string, err error) {
+	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)
 }
 
 func findMeta(creds SourceCredentials) (beamtimeMeta, error) {
@@ -204,31 +207,30 @@ func findMeta(creds SourceCredentials) (beamtimeMeta, error) {
 	return meta, nil
 }
 
-func authorizeMeta(meta beamtimeMeta, request authorizationRequest, creds SourceCredentials) error {
-
+func authorizeMeta(meta beamtimeMeta, request authorizationRequest, creds SourceCredentials) (accessType string, err error) {
+	accessType = ""
 	if creds.Type=="raw" && meta.OnlinePath=="" {
 		err_string := "beamtime "+meta.BeamtimeId+" is not online"
 		log.Error(err_string)
-		return errors.New(err_string)
+		return "",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 errors.New(err_string)
+		return "",errors.New(err_string)
 	}
 
 	if needHostAuthorization(creds) {
 		if err := authorizeByHost(request.OriginHost, meta.Beamline); err != nil {
-			return err
+			return "",err
 		}
+		accessType = "write"
 	} else {
-		if err := authorizeByToken(creds); err != nil {
-			return err
-		}
+		accessType,err = authorizeByToken(creds)
 	}
 
-	return nil
+	return accessType,err
 }
 
 func authorize(request authorizationRequest, creds SourceCredentials) (beamtimeMeta, error) {
@@ -241,11 +243,14 @@ func authorize(request authorizationRequest, creds SourceCredentials) (beamtimeM
 		return beamtimeMeta{}, err
 	}
 
-	if err := authorizeMeta(meta, request, creds); err != nil {
+	var accessType string
+	if accessType, err = authorizeMeta(meta, request, creds); err != nil {
 		return beamtimeMeta{}, err
 	}
 
-	log.Debug("authorized beamtime " + meta.BeamtimeId + " for " + request.OriginHost + " in " + meta.Beamline+", type "+meta.Type)
+	meta.AccessType = accessType
+	log.Debug("authorized beamtime " + meta.BeamtimeId + " for " + request.OriginHost + " in " +
+		meta.Beamline+", type "+meta.Type +"access type: "+accessType)
 	return meta, nil
 }
 
diff --git a/authorizer/src/asapo_authorizer/server/authorize_test.go b/authorizer/src/asapo_authorizer/server/authorize_test.go
index 4085b1b5b473ebbae4a06998e73e509ddee12c9b..513969baf68a3048fc8ea9b2a923e8d0418d0f84 100644
--- a/authorizer/src/asapo_authorizer/server/authorize_test.go
+++ b/authorizer/src/asapo_authorizer/server/authorize_test.go
@@ -1,8 +1,10 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/common"
 	"asapo_authorizer/ldap_client"
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"github.com/stretchr/testify/assert"
 	"io/ioutil"
@@ -14,9 +16,27 @@ import (
 	"testing"
 )
 
-func prepareToken(beamtime_or_beamline string) string{
-	authHMAC = utils.NewHMACAuth("secret")
-	token, _ := authHMAC.GenerateToken(&beamtime_or_beamline)
+
+func prepareUserToken(payload string, accessType string) string{
+	auth := authorization.NewAuth(nil,utils.NewJWTAuth("secret_user"),nil)
+	var claims utils.CustomClaims
+	var extraClaim structs.AccessTokenExtraClaim
+	claims.Subject = payload
+	extraClaim.AccessType = accessType
+	claims.ExtraClaims = &extraClaim
+	token, _ := auth.AdminAuth().GenerateToken(&claims)
+	return token
+}
+
+func prepareAdminToken(payload string) string{
+	auth:= authorization.NewAuth(nil,utils.NewJWTAuth("secret_admin"),nil)
+
+	var claims utils.CustomClaims
+	var extraClaim structs.AccessTokenExtraClaim
+	claims.Subject = payload
+	extraClaim.AccessType = "create"
+	claims.ExtraClaims = &extraClaim
+	token, _ := auth.AdminAuth().GenerateToken(&claims)
 	return token
 }
 
@@ -44,9 +64,12 @@ func makeRequest(request interface{}) string {
 	return string(buf)
 }
 
-func doPostRequest(path string,buf 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)
+	}
 	w := httptest.NewRecorder()
 	mux.ServeHTTP(w, req)
 	return w
@@ -86,9 +109,9 @@ func TestSplitCreds(t *testing.T) {
 }
 
 func TestAuthorizeDefaultOK(t *testing.T) {
-	allowBeamlines([]beamtimeMeta{{"asapo_test","beamline","","2019","tf",""}})
+	allowBeamlines([]beamtimeMeta{{"asapo_test","beamline","","2019","tf","",""}})
 	request :=  makeRequest(authorizationRequest{"processed%asapo_test%%%","host"})
-	w := doPostRequest("/authorize",request)
+	w := doPostRequest("/authorize",request,"")
 
 	body, _ := ioutil.ReadAll(w.Body)
 
@@ -157,38 +180,38 @@ var authTests = [] struct {
 	message string
 	answer string
 }{
-	{"processed","test","auto","dataSource", prepareToken("test"),"127.0.0.2",http.StatusOK,"user source with correct token",
-		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed"}`},
-	{"processed","test_online","auto","dataSource", prepareToken("test_online"),"127.0.0.1",http.StatusOK,"with online path, processed type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed"}`},
-	{"processed","test1","auto","dataSource", prepareToken("test1"),"127.0.0.1",http.StatusUnauthorized,"correct token, beamtime not found",
+	{"processed","test","auto","dataSource", prepareUserToken("bt_test","write"),"127.0.0.2",http.StatusOK,"user source with correct token",
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-type":"write"}`},
+	{"processed","test_online","auto","dataSource", prepareUserToken("bt_test_online","read"),"127.0.0.1",http.StatusOK,"with online path, processed type",
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed","access-type":"read"}`},
+	{"processed","test1","auto","dataSource", prepareUserToken("bt_test1","read"),"127.0.0.1",http.StatusUnauthorized,"correct token, beamtime not found",
 		""},
-	{"processed","test","auto","dataSource", prepareToken("wrong"),"127.0.0.1",http.StatusUnauthorized,"user source with wrong token",
+	{"processed","test","auto","dataSource", prepareUserToken("wrong","read"),"127.0.0.1",http.StatusUnauthorized,"user source with wrong token",
 		""},
-	{"processed","test","bl1","dataSource", prepareToken("test"),"127.0.0.1",http.StatusOK,"correct beamline given",
-		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed"}`},
-		{"processed","test","bl2","dataSource", prepareToken("test"),"127.0.0.1",http.StatusUnauthorized,"incorrect beamline given",
+	{"processed","test","bl1","dataSource", prepareUserToken("bt_test","read"),"127.0.0.1",http.StatusOK,"correct beamline given",
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-type":"read"}`},
+		{"processed","test","bl2","dataSource", prepareUserToken("bt_test","read"),"127.0.0.1",http.StatusUnauthorized,"incorrect beamline given",
 		""},
-	{"processed","auto","p07", "dataSource",prepareToken("bl_p07"),"127.0.0.1",http.StatusOK,"beamtime found",
-		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","core-path":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed"}`},
-	{"processed","auto","p07", "dataSource",prepareToken("bl_p06"),"127.0.0.1",http.StatusUnauthorized,"wrong token",
+	{"processed","auto","p07", "dataSource", prepareUserToken("bl_p07","read"),"127.0.0.1",http.StatusOK,"beamtime found",
+		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","core-path":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed","access-type":"read"}`},
+	{"processed","auto","p07", "dataSource", prepareUserToken("bl_p06","read"),"127.0.0.1",http.StatusUnauthorized,"wrong token",
 		""},
-	{"processed","auto","p08", "dataSource",prepareToken("bl_p08"),"127.0.0.1",http.StatusUnauthorized,"beamtime not found",
+	{"processed","auto","p08", "dataSource", prepareUserToken("bl_p08","read"),"127.0.0.1",http.StatusUnauthorized,"beamtime not found",
 		""},
-	{"raw","test_online","auto","dataSource", prepareToken("test_online"),"127.0.0.1",http.StatusOK,"raw type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw"}`},
 	{"raw","test_online","auto","dataSource", "","127.0.0.1",http.StatusOK,"raw type",
-		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw"}`},
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-type":"write"}`},
+	{"raw","test_online","auto","dataSource", "","127.0.0.1",http.StatusOK,"raw type",
+		`{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-type":"write"}`},
  	{"raw","auto","p07","dataSource", "","127.0.0.1",http.StatusOK,"raw type, auto beamtime",
-		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","core-path":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw"}`},
+		`{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","core-path":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-type":"write"}`},
 	{"raw","auto","p07","noldap", "","127.0.0.1",http.StatusNotFound,"no conection to ldap",
 		""},
 	{"raw","test_online","auto","dataSource", "","127.0.0.2",http.StatusUnauthorized,"raw type, wrong origin host",
 		""},
-	{"raw","test","auto","dataSource", prepareToken("test"),"127.0.0.1",http.StatusUnauthorized,"raw when not online",
+	{"raw","test","auto","dataSource", prepareUserToken("bt_test","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","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed"}`},
+		`{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","core-path":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-type":"write"}`},
 	{"processed","test","auto","dataSource", "","127.0.0.2",http.StatusUnauthorized,"processed without token, wrong host",
 		""},
 }
@@ -196,7 +219,7 @@ var authTests = [] struct {
 func TestAuthorize(t *testing.T) {
 	ldapClient = mockClient
 	allowBeamlines([]beamtimeMeta{})
-
+	Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret"))
 	expected_uri := "expected_uri"
 	expected_base := "expected_base"
 	allowed_ips := []string{"127.0.0.1"}
@@ -231,7 +254,7 @@ func TestAuthorize(t *testing.T) {
 		}
 
 		request :=  makeRequest(authorizationRequest{test.source_type+"%"+test.beamtime_id+"%"+test.beamline+"%"+test.dataSource+"%"+test.token,test.originHost})
-		w := doPostRequest("/authorize",request)
+		w := doPostRequest("/authorize",request,"")
 
 		body, _ := ioutil.ReadAll(w.Body)
 		if test.status==http.StatusOK {
@@ -248,24 +271,24 @@ func TestAuthorize(t *testing.T) {
 
 func TestNotAuthorized(t *testing.T) {
 	request :=  makeRequest(authorizationRequest{"raw%any_id%%%","host"})
-	w := doPostRequest("/authorize",request)
+	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([]beamtimeMeta{{"test","beamline","","2019","tf",""}})
+	allowBeamlines([]beamtimeMeta{{"test","beamline","","2019","tf","",""}})
 
 	request :=  authorizationRequest{"asapo_test%%","host"}
 	creds,_ := getSourceCredentials(request)
diff --git a/authorizer/src/asapo_authorizer/server/folder_token.go b/authorizer/src/asapo_authorizer/server/folder_token.go
index bb69d5b9b34a56169a596c8c2cbec13db7fc6fd7..f29a5b318b87042c040ddbe950927ca778b20a1c 100644
--- a/authorizer/src/asapo_authorizer/server/folder_token.go
+++ b/authorizer/src/asapo_authorizer/server/folder_token.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"net/http"
 	"time"
@@ -25,13 +26,12 @@ type folderToken struct {
 
 func prepareJWTToken(request folderTokenRequest) (string,error) {
 	var claims utils.CustomClaims
-	var extraClaim utils.FolderTokenTokenExtraClaim
+	var extraClaim structs.FolderTokenTokenExtraClaim
 
 	extraClaim.RootFolder = request.Folder
 	claims.ExtraClaims = &extraClaim
-	claims.Duration = time.Duration(settings.TokenDurationMin) * time.Minute
-
-	return authJWT.GenerateToken(&claims)
+	claims.SetExpiration(time.Duration(settings.FolderTokenDurationMin) * time.Minute)
+	return Auth.JWTAuth().GenerateToken(&claims)
 
 }
 
@@ -40,14 +40,8 @@ func folderTokenResponce(token string) []byte{
 }
 
 func checkBeamtimeToken(request folderTokenRequest) error {
-	token_expect, _ := authHMAC.GenerateToken(&request.BeamtimeId)
-	var err_string string
-	if request.Token != token_expect {
-		err_string = "wrong token for beamtime " + request.BeamtimeId
-		log.Error(err_string)
-		return errors.New(err_string)
-	}
-	return nil
+	_,err :=  checkToken(request.Token,utils.SubjectFromBeamtime(request.BeamtimeId))
+	return err
 }
 
 
diff --git a/authorizer/src/asapo_authorizer/server/folder_token_test.go b/authorizer/src/asapo_authorizer/server/folder_token_test.go
index dbd48e2c42ad871d4157cf9b97e9af8677de9d99..0e1c1aa232f2bc2d4423a4d692d9a9f271b19f71 100644
--- a/authorizer/src/asapo_authorizer/server/folder_token_test.go
+++ b/authorizer/src/asapo_authorizer/server/folder_token_test.go
@@ -1,6 +1,8 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"github.com/stretchr/testify/assert"
 	"io/ioutil"
@@ -18,19 +20,21 @@ var  fodlerTokenTests = [] struct {
 	status int
 	message string
 }{
-	{"test", "tf/gpfs/bl1/2019/data/test",prepareToken("test"),http.StatusOK,"beamtime found"},
-	{"test_online", "bl1/current",prepareToken("test_online"),http.StatusOK,"online beamtime found"},
-	{"test", "bl1/current",prepareToken("test"),http.StatusUnauthorized,"no online beamtime found"},
-	{"test_online", "bl2/current",prepareToken("test_online"),http.StatusUnauthorized,"wrong online folder"},
-	{"test", "tf/gpfs/bl1/2019/data/test1",prepareToken("test"),http.StatusUnauthorized,"wrong folder"},
-	{"test", "tf/gpfs/bl1/2019/data/test",prepareToken("test1"),http.StatusUnauthorized,"wrong token"},
-	{"11111111", "tf/gpfs/bl1/2019/data/test",prepareToken("11111111"),http.StatusBadRequest,"bad request"},
+	{"test", "tf/gpfs/bl1/2019/data/test", prepareUserToken("bt_test","read"),http.StatusOK,"beamtime found"},
+/*	{"test_online", "bl1/current", prepareUserToken("bt_test_online","read"),http.StatusOK,"online beamtime found"},
+	{"test", "bl1/current", prepareUserToken("bt_test","read"),http.StatusUnauthorized,"no online beamtime found"},
+	{"test_online", "bl2/current", prepareUserToken("bt_test_online","read"),http.StatusUnauthorized,"wrong online folder"},
+	{"test", "tf/gpfs/bl1/2019/data/test1", prepareUserToken("bt_test","read"),http.StatusUnauthorized,"wrong folder"},
+	{"test", "tf/gpfs/bl1/2019/data/test", prepareUserToken("bt_test1","read"),http.StatusUnauthorized,"wrong token"},
+	{"11111111", "tf/gpfs/bl1/2019/data/test", prepareUserToken("bt_11111111","read"),http.StatusBadRequest,"bad request"},*/
 }
 
 func TestFolderToken(t *testing.T) {
 	allowBeamlines([]beamtimeMeta{})
 	settings.RootBeamtimesFolder ="."
 	settings.CurrentBeamlinesFolder="."
+	Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"),utils.NewJWTAuth("secret_admin"),utils.NewJWTAuth("secret_folder"))
+
 	os.MkdirAll(filepath.Clean("tf/gpfs/bl1/2019/data/test"), os.ModePerm)
 	os.MkdirAll(filepath.Clean("tf/gpfs/bl1/2019/data/test_online"), os.ModePerm)
 
@@ -41,17 +45,16 @@ func TestFolderToken(t *testing.T) {
 	defer 	os.RemoveAll("bl1")
 
 	for _, test := range fodlerTokenTests {
-		authJWT = utils.NewJWTAuth("secret")
 		abs_path:=settings.RootBeamtimesFolder + string(filepath.Separator)+test.root_folder
 		request :=  makeRequest(folderTokenRequest{abs_path,test.beamtime_id,test.token})
 		if test.status == http.StatusBadRequest {
 			request =makeRequest(authorizationRequest{})
 		}
-		w := doPostRequest("/folder",request)
+		w := doPostRequest("/folder",request,"")
 		if w.Code == http.StatusOK {
 			body, _ := ioutil.ReadAll(w.Body)
-			claims,_ := utils.CheckJWTToken(string(body),"secret")
-			var extra_claim utils.FolderTokenTokenExtraClaim
+			claims,_ := utils.CheckJWTToken(string(body),"secret_folder")
+			var extra_claim structs.FolderTokenTokenExtraClaim
 			utils.MapToStruct(claims.(*utils.CustomClaims).ExtraClaims.(map[string]interface{}), &extra_claim)
 			assert.Equal(t, abs_path, extra_claim.RootFolder, test.message)
 		} else {
diff --git a/authorizer/src/asapo_authorizer/server/introspect.go b/authorizer/src/asapo_authorizer/server/introspect.go
new file mode 100644
index 0000000000000000000000000000000000000000..e6c07a31fd6faa017e71ac7f4d89f5823c8a008a
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/server/introspect.go
@@ -0,0 +1,48 @@
+package server
+
+import (
+	log "asapo_common/logger"
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"encoding/json"
+	"net/http"
+)
+
+func extractToken(r *http.Request) (string, error) {
+	var request structs.IntrospectTokenRequest
+	err := utils.ExtractRequest(r, &request)
+	if err != nil {
+		return "", err
+	}
+	return request.Token, nil
+}
+
+func verifyUserToken(token string) (response structs.IntrospectTokenResponse, err error) {
+	var extra_claim structs.AccessTokenExtraClaim
+	response.Sub,err = Auth.UserAuth().CheckAndGetContent(token,&extra_claim)
+	if err!=nil {
+		return
+	}
+	response.AccessType = extra_claim.AccessType
+	return
+}
+
+func routeIntrospect(w http.ResponseWriter, r *http.Request) {
+	token, err := extractToken(r)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusBadRequest)
+		return
+	}
+
+	response,err := verifyUserToken(token)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusUnauthorized)
+		return
+	}
+
+	log.Debug("verified user token for "+response.Sub)
+
+	answer,_ := json.Marshal(&response)
+	w.WriteHeader(http.StatusOK)
+	w.Write(answer)
+}
diff --git a/authorizer/src/asapo_authorizer/server/introspect_test.go b/authorizer/src/asapo_authorizer/server/introspect_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..28d13b1c899ef72a37837aaa17a2c906cbe96c9c
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/server/introspect_test.go
@@ -0,0 +1,51 @@
+package server
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"encoding/json"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"io/ioutil"
+	"net/http"
+	"testing"
+)
+
+var  IntrospectTests = [] struct {
+	tokenSubject string
+	role string
+	status int
+	message string
+}{
+	{"bt_test","read",http.StatusOK,"valid token"},
+	{"","",http.StatusUnauthorized,"invalid token"},
+
+}
+
+func TestIntrospect(t *testing.T) {
+	authJWT := utils.NewJWTAuth("secret")
+	authAdmin := utils.NewJWTAuth("secret_admin")
+	authUser := utils.NewJWTAuth("secret_user")
+	Auth = authorization.NewAuth(authUser,authAdmin,authJWT)
+	for _, test := range IntrospectTests {
+		token := prepareUserToken(test.tokenSubject,test.role)
+		if test.status==http.StatusUnauthorized {
+			token = "blabla"
+		}
+		request :=  makeRequest(structs.IntrospectTokenRequest{token})
+		w := doPostRequest("/introspect",request,"")
+		assert.Equal(t, test.status , w.Code, test.message)
+		if test.status == http.StatusOK {
+			body, _ := ioutil.ReadAll(w.Body)
+			var token structs.IntrospectTokenResponse
+			json.Unmarshal(body,&token)
+			assert.Equal(t, token.Sub , test.tokenSubject, test.message)
+			assert.Equal(t, token.AccessType , test.role, test.message)
+		} else {
+			body, _ := ioutil.ReadAll(w.Body)
+			fmt.Println(string(body))
+		}
+	}
+}
+
diff --git a/authorizer/src/asapo_authorizer/server/issue_token.go b/authorizer/src/asapo_authorizer/server/issue_token.go
new file mode 100644
index 0000000000000000000000000000000000000000..b4f534d83cc207a8931cde5636d63f371ae7ee28
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/server/issue_token.go
@@ -0,0 +1,74 @@
+package server
+
+import (
+	"asapo_authorizer/authorization"
+	log "asapo_common/logger"
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"errors"
+	"net/http"
+)
+
+func extractUserTokenrequest(r *http.Request) (request structs.IssueTokenRequest, err error) {
+	err = utils.ExtractRequest(r, &request)
+	if err != nil {
+		return request, err
+	}
+
+	if request.Subject["beamtimeId"] == "" && request.Subject["beamline"] == "" {
+		return request, errors.New("missing beamtime/beamline")
+	}
+
+	if request.Subject["beamtimeId"] != "" && request.Subject["beamline"] != "" {
+		return request, errors.New("set only one of beamtime/beamline")
+	}
+
+	if request.DaysValid<=0 {
+		return request, errors.New("set token valid period")
+	}
+
+	if request.AccessType != "read" && request.AccessType != "write" {
+		return request, errors.New("wrong access type: " + request.AccessType)
+	}
+
+	return request, nil
+}
+
+func routeAuthorisedTokenIssue(w http.ResponseWriter, r *http.Request) {
+	Auth.AdminAuth().ProcessAuth(checkAccessToken, "admin")(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" || extraClaim.AccessType != "create" {
+		err_txt := "wrong token claims"
+		w.WriteHeader(http.StatusUnauthorized)
+		w.Write([]byte(err_txt))
+	}
+
+	issueUserToken(w, r)
+}
+
+func issueUserToken(w http.ResponseWriter, r *http.Request) {
+	request, err := extractUserTokenrequest(r)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusBadRequest)
+		return
+	}
+
+	token, err := Auth.PrepareAccessToken(request,true)
+	if err != nil {
+		utils.WriteServerError(w, err, http.StatusInternalServerError)
+		return
+	}
+
+	log.Debug("generated user token ")
+
+	answer := authorization.UserTokenResponce(request, token)
+	w.WriteHeader(http.StatusOK)
+	w.Write(answer)
+}
diff --git a/authorizer/src/asapo_authorizer/server/issue_token_test.go b/authorizer/src/asapo_authorizer/server/issue_token_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..223af38d80ce2d671ac9332bc325a28d7ffee467
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/server/issue_token_test.go
@@ -0,0 +1,65 @@
+package server
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_common/structs"
+	"asapo_common/utils"
+	"encoding/json"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"io/ioutil"
+	"net/http"
+	"testing"
+	"time"
+)
+
+var  IssueTokenTests = [] struct {
+	requestSubject map[string]string
+	tokenSubject string
+	role string
+	validDays int
+	adminToken string
+	resToken string
+	status int
+	message string
+}{
+	{map[string]string{"beamtimeId":"test"},"bt_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamtime"},
+	{map[string]string{"beamtimeId":"test"},"bt_test","read",90,prepareAdminToken("admin"),"aaa",http.StatusOK,"write for beamtime"},
+	{map[string]string{"beamline":"test"},"bl_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamline"},
+	{map[string]string{"blabla":"test"},"","read",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"beamline or beamtime not given"},
+	{map[string]string{"beamtimeId":"test"},"","bla",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"wrong role"},
+	{map[string]string{"beamtimeId":"test"},"","read",180,prepareAdminToken("bla"),"",http.StatusUnauthorized,"wrong admin token"},
+	{map[string]string{"beamtimeId":"test"},"bt_test","read",0,prepareAdminToken("admin"),"aaa",http.StatusBadRequest,"0 valid days"},
+
+}
+
+func TestIssueToken(t *testing.T) {
+	authJWT := utils.NewJWTAuth("secret")
+	authAdmin := utils.NewJWTAuth("secret_admin")
+	authUser := utils.NewJWTAuth("secret_user")
+	Auth = authorization.NewAuth(authUser,authAdmin,authJWT)
+	for _, test := range IssueTokenTests {
+		request :=  makeRequest(structs.IssueTokenRequest{test.requestSubject,test.validDays,test.role})
+		w := doPostRequest("/admin/issue",request,authAdmin.Name()+" "+test.adminToken)
+		if w.Code == http.StatusOK {
+			body, _ := ioutil.ReadAll(w.Body)
+			var token structs.IssueTokenResponse
+			json.Unmarshal(body,&token)
+			claims,_ := utils.CheckJWTToken(token.Token,"secret_user")
+			cclaims,_:= claims.(*utils.CustomClaims)
+			var extra_claim structs.AccessTokenExtraClaim
+			utils.MapToStruct(claims.(*utils.CustomClaims).ExtraClaims.(map[string]interface{}), &extra_claim)
+			assert.Equal(t, cclaims.Subject , test.tokenSubject, test.message)
+			assert.True(t, cclaims.ExpiresAt-time.Now().Unix()>int64(test.validDays)*24*60*60-10, test.message)
+			assert.True(t, cclaims.ExpiresAt-time.Now().Unix()<int64(test.validDays)*24*60*60+10, test.message)
+			assert.Equal(t, extra_claim.AccessType, test.role, test.message)
+			assert.NotEmpty(t, cclaims.Id , test.message)
+		} else {
+			body, _ := ioutil.ReadAll(w.Body)
+			fmt.Println(string(body))
+		}
+
+		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 9f8e562b5ddad13f54363f25599f16420440ca80..370dd9dfa5b9cc40fd8f9db92ca4cd4449e06d21 100644
--- a/authorizer/src/asapo_authorizer/server/listroutes.go
+++ b/authorizer/src/asapo_authorizer/server/listroutes.go
@@ -11,6 +11,12 @@ var listRoutes = utils.Routes{
 		"/authorize",
 		routeAuthorize,
 	},
+	utils.Route{
+		"Authorize",
+		"POST",
+		"/introspect",
+		routeIntrospect,
+	},
 	utils.Route{
 		"HealthCheck",
 		"Get",
@@ -23,4 +29,10 @@ var listRoutes = utils.Routes{
 		"/folder",
 		routeFolderToken,
 	},
+	utils.Route{
+		"User Token",
+		"POST",
+		"/admin/issue",
+		routeAuthorisedTokenIssue,
+	},
 }
diff --git a/authorizer/src/asapo_authorizer/server/server.go b/authorizer/src/asapo_authorizer/server/server.go
index 7dc7aca8c467718c6324eb55e131b2da8c8defb7..9e01e914cdd3498b97ca608fdb2dc6319936dc11 100644
--- a/authorizer/src/asapo_authorizer/server/server.go
+++ b/authorizer/src/asapo_authorizer/server/server.go
@@ -1,8 +1,8 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/ldap_client"
-	"asapo_common/utils"
 )
 
 type  beamtimeMeta struct {
@@ -12,17 +12,19 @@ type  beamtimeMeta struct {
 	OfflinePath string `json:"core-path"`
 	OnlinePath string `json:"beamline-path"`
 	Type string `json:"source-type"`
+	AccessType string `json:"access-type"`
 }
 
 type serverSettings struct {
-	Port                    int
-	LogLevel                string
-	RootBeamtimesFolder     string
+	Port                   int
+	LogLevel               string
+	RootBeamtimesFolder    string
 	CurrentBeamlinesFolder string
-	AlwaysAllowedBeamtimes  []beamtimeMeta
-	SecretFile              string
-	TokenDurationMin    	int
-	Ldap struct {
+	AlwaysAllowedBeamtimes []beamtimeMeta
+	UserSecretFile         string
+	AdminSecretFile        string
+	FolderTokenDurationMin int
+	Ldap                   struct {
 		Uri string
 		BaseDn string
 		FilterTemplate string
@@ -31,6 +33,5 @@ type serverSettings struct {
 
 var settings serverSettings
 var ldapClient ldap_client.LdapClient
-var authHMAC utils.Auth
-var authJWT utils.Auth
+var Auth *authorization.Auth
 
diff --git a/authorizer/src/asapo_authorizer/server/server_nottested.go b/authorizer/src/asapo_authorizer/server/server_nottested.go
index b141dcd960de570e86e3c57e2f062bb4983c17b1..2f428370f6955303d582f7bd22a551cb4dace88c 100644
--- a/authorizer/src/asapo_authorizer/server/server_nottested.go
+++ b/authorizer/src/asapo_authorizer/server/server_nottested.go
@@ -3,6 +3,7 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/ldap_client"
 	log "asapo_common/logger"
 	"asapo_common/utils"
@@ -14,21 +15,24 @@ import (
 
 func Start() {
 	mux := utils.NewRouter(listRoutes)
-	ldapClient = new (ldap_client.OpenLdapClient)
+	ldapClient = new(ldap_client.OpenLdapClient)
 	log.Info("Starting ASAPO Authorizer, version " + version.GetVersion())
 	log.Info("Listening on port: " + strconv.Itoa(settings.Port))
 	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(settings.Port), http.HandlerFunc(mux.ServeHTTP)))
 }
 
-func createAuth() (utils.Auth,utils.Auth, error) {
-	secret, err := utils.ReadFirstStringFromFile(settings.SecretFile)
+func createAuth() (*authorization.Auth,error) {
+	secret, err := utils.ReadFirstStringFromFile(settings.UserSecretFile)
 	if err != nil {
-		return nil,nil, err
+		return nil, err
 	}
-	return utils.NewHMACAuth(secret),utils.NewJWTAuth(secret), nil
+	adminSecret, err := utils.ReadFirstStringFromFile(settings.AdminSecretFile)
+	if err != nil {
+		return nil, err
+	}
+	return authorization.NewAuth(utils.NewJWTAuth(secret), utils.NewJWTAuth(adminSecret), utils.NewJWTAuth(secret)),nil
 }
 
-
 func ReadConfig(fname string) (log.Level, error) {
 	if err := utils.ReadJsonFromFile(fname, &settings); err != nil {
 		return log.FatalLevel, err
@@ -38,12 +42,16 @@ func ReadConfig(fname string) (log.Level, error) {
 		return log.FatalLevel, errors.New("Server port not set")
 	}
 
-	if settings.SecretFile == "" {
-		return log.FatalLevel, errors.New("Secret file not set")
+	if settings.UserSecretFile == "" {
+		return log.FatalLevel, errors.New("User secret file not set")
+	}
+
+	if settings.AdminSecretFile == "" {
+		return log.FatalLevel, errors.New("Admin secret file not set")
 	}
 
 	var err error
-	authHMAC,authJWT, err = createAuth()
+	Auth, err = createAuth()
 	if err != nil {
 		return log.FatalLevel, err
 	}
diff --git a/broker/CMakeLists.txt b/broker/CMakeLists.txt
index d21235b49dc5cf7b4ba53364ed734deabe75e8b8..8d4e3ca3fe26d274ed69971a75274a6e7c9fdabf 100644
--- a/broker/CMakeLists.txt
+++ b/broker/CMakeLists.txt
@@ -1,20 +1,8 @@
 set (TARGET_NAME asapo-broker)
 
-if (NOT "$ENV{GOPATH}" STREQUAL "")
-	set(GOPATH $ENV{GOPATH})
-endif()
-
-if (NOT GOPATH)
-    message (FATAL_ERROR "GOPATH not set")
-endif()
-
-message(STATUS "global gopath ${GOPATH}")
-
 IF(WIN32)
-    set (gopath "${GOPATH}\;${CMAKE_CURRENT_SOURCE_DIR}\;${CMAKE_SOURCE_DIR}/common/go")
     set (exe_name "${TARGET_NAME}.exe")
 ELSE()
-    set (gopath ${GOPATH}:${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_SOURCE_DIR}/common/go)
     set (exe_name "${TARGET_NAME}")
 ENDIF()
 
@@ -23,8 +11,8 @@ include(testing_go)
 configure_file(docker/Dockerfile . COPYONLY)
 
 add_custom_target(asapo-broker ALL
-    COMMAND  ${CMAKE_COMMAND} -E env GOPATH=${gopath}
-    go build ${GO_OPTS} -o ${exe_name} asapo_broker/main
+    COMMAND go build ${GO_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} main/broker.go
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_broker
     VERBATIM)
 define_property(TARGET PROPERTY EXENAME
         BRIEF_DOCS <executable name>
@@ -32,6 +20,8 @@ define_property(TARGET PROPERTY EXENAME
 
 set_target_properties(asapo-broker PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name})
 
-gotest(${TARGET_NAME} "${CMAKE_CURRENT_SOURCE_DIR}" "./...")
-go_integration_test(${TARGET_NAME}-connectdb "./..." "MongoDBConnect")
-go_integration_test(${TARGET_NAME}-nextrecord "./..." "MongoDBNext")
+gotest(${TARGET_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_broker" "./...")
+
+
+go_integration_test(${TARGET_NAME}-connectdb "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_broker" "./..." "MongoDBConnect")
+go_integration_test(${TARGET_NAME}-nextrecord "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_broker" "./..." "MongoDBNext")
diff --git a/broker/src/asapo_broker/database/mongodb_query.go b/broker/src/asapo_broker/database/mongodb_query.go
index faa6f718b6d2dfd02abdd393596acf881d7db6ff..7348ac93ec6d1726eb8c70d5158104d7f7b86141 100644
--- a/broker/src/asapo_broker/database/mongodb_query.go
+++ b/broker/src/asapo_broker/database/mongodb_query.go
@@ -6,7 +6,7 @@ import (
 	"errors"
 	"fmt"
 	"go.mongodb.org/mongo-driver/bson"
-	"github.com/knocknote/vitess-sqlparser/sqlparser"
+	"github.com/blastrain/vitess-sqlparser/sqlparser"
 	"strconv"
 )
 
diff --git a/broker/src/asapo_broker/database/mongodb_test.go b/broker/src/asapo_broker/database/mongodb_test.go
index 7727b1a99e4ea88bc8ca0d27faef1c1ea960e6dd..b0f2e97a38901e168cb1964a44beacb2de73593a 100644
--- a/broker/src/asapo_broker/database/mongodb_test.go
+++ b/broker/src/asapo_broker/database/mongodb_test.go
@@ -216,7 +216,7 @@ func insertRecords(n int) {
 	records := make([]TestRecord, n)
 	for ind, record := range records {
 		record.ID = int64(ind) + 1
-		record.Name = string(ind)
+		record.Name = fmt.Sprint(ind)
 		if err := db.insertRecord(dbname, collection, &record); err != nil {
 			fmt.Println("error at insert ", ind)
 		}
diff --git a/broker/src/asapo_broker/go.mod b/broker/src/asapo_broker/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..c8b56219b5cb323e672fe6ef4553a0e8ae9ac766
--- /dev/null
+++ b/broker/src/asapo_broker/go.mod
@@ -0,0 +1,17 @@
+module asapo_broker
+
+go 1.16
+
+replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common
+
+require (
+	asapo_common v0.0.0
+	github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+	github.com/gorilla/mux v1.8.0
+	github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab
+	github.com/rs/xid v1.2.1
+	github.com/sirupsen/logrus v1.8.0 // indirect
+	github.com/stretchr/testify v1.7.0
+	go.mongodb.org/mongo-driver v1.4.6
+)
diff --git a/broker/src/asapo_broker/go.sum b/broker/src/asapo_broker/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..91043be57853e6ad739921a2277e8c718f1e8a84
--- /dev/null
+++ b/broker/src/asapo_broker/go.sum
@@ -0,0 +1,142 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
+github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
+github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba h1:hBK2BWzm0OzYZrZy9yzvZZw59C5Do4/miZ8FhEwd5P8=
+github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba/go.mod h1:FGQp+RNQwVmLzDq6HBrYCww9qJQyNwH9Qji/quTQII4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
+github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
+github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
+github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
+github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
+github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
+github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
+github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
+github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
+github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
+github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
+github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
+github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
+github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
+github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
+github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
+github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig=
+github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68 h1:d2hBkTvi7B89+OXY8+bBBshPlc+7JYacGrG/dFak8SQ=
+github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
+github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
+github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
+github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
+github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
+github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
+github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
+github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
+go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.0.0-20180302201248-b7ef84aaf62a/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/broker/src/asapo_broker/server/authorizer.go b/broker/src/asapo_broker/server/authorizer.go
new file mode 100644
index 0000000000000000000000000000000000000000..abe6e353b98c1b54abbded439b98af0fe3eb602b
--- /dev/null
+++ b/broker/src/asapo_broker/server/authorizer.go
@@ -0,0 +1,125 @@
+package server
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"io"
+	"net/http"
+	"sync"
+	"time"
+)
+
+type Token struct {
+	Sub string
+	AccessType string
+}
+
+type Authorizer interface {
+	AuthorizeToken(tokenJWT string) (token Token, err error)
+}
+
+type HttpClient interface {
+	Do(req *http.Request) (*http.Response, error)
+}
+
+type HttpError struct{
+	err error
+	statusCode int
+}
+
+func (m *HttpError) Error() string {
+	return m.err.Error()
+}
+
+
+type AsapoAuthorizer struct {
+	serverUrl string
+	httpClient HttpClient
+}
+
+type cachedToken struct{
+	Token
+	lastUpdate time.Time
+}
+
+var cachedTokens  = struct {
+	tokens map[string]cachedToken
+	cachedTokensLock sync.RWMutex
+}{tokens:make(map[string]cachedToken,0)}
+
+func getCachedToken(tokenJWT string)(token Token, ok bool) {
+	cachedTokens.cachedTokensLock.RLock()
+	defer cachedTokens.cachedTokensLock.RUnlock()
+	cachedToken,ok:=cachedTokens.tokens[tokenJWT]
+	if !ok{
+		return  token,false
+	}
+	if time.Now().Sub(cachedToken.lastUpdate) < 10000*time.Second {
+		return cachedToken.Token, true
+	}
+	return token,false
+}
+
+func cacheToken(tokenJWT string,token Token) {
+	cachedTokens.cachedTokensLock.Lock()
+	defer cachedTokens.cachedTokensLock.Unlock()
+
+	cachedTokens.tokens[tokenJWT] = cachedToken{
+		Token:      token,
+		lastUpdate: time.Now(),
+	}
+}
+
+func (a * AsapoAuthorizer) doRequest(req *http.Request) (token Token, err error) {
+	resp, err := a.httpClient.Do(req)
+	if err != nil {
+		return token, err
+	}
+	defer resp.Body.Close()
+
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return token, err
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return token, &HttpError{errors.New("returned " + resp.Status + ": " + string(body)),resp.StatusCode}
+	}
+
+	err = json.Unmarshal(body, &token)
+	return
+}
+func createIntrospectTokenRequest(tokenJWT string) (*http.Request, error) {
+	path := "http://"+settings.AuthorizationServer + "/introspect"
+	request := struct {
+		Token string
+	}{tokenJWT}
+	json_data, _ := json.Marshal(request)
+	req, err := http.NewRequest("POST", path, bytes.NewBuffer(json_data))
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Add("Content-Type", "application/json")
+	return req, nil
+}
+
+func (a * AsapoAuthorizer) AuthorizeToken(tokenJWT string) (token Token, err error) {
+	token,ok := getCachedToken(tokenJWT)
+	if ok {
+		return
+	}
+
+	req, err := createIntrospectTokenRequest(tokenJWT)
+	if err != nil {
+		return
+	}
+
+	token, err = a.doRequest(req)
+	if err == nil {
+		cacheToken(tokenJWT, token)
+	}
+
+	return
+}
+
diff --git a/broker/src/asapo_broker/server/authorizer_test.go b/broker/src/asapo_broker/server/authorizer_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..baf060dc8a4129cf60a4faadf1f5bae1a059055c
--- /dev/null
+++ b/broker/src/asapo_broker/server/authorizer_test.go
@@ -0,0 +1,98 @@
+package server
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+	"io/ioutil"
+	"net/http"
+	"testing"
+)
+
+type MockClient struct {
+	mock.Mock
+}
+
+const expectedAuthorizerUri="http://authorizer:8400/introspect"
+const expectedToken="blabla"
+
+
+func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
+	args := m.Called(req)
+	return args.Get(0).(*http.Response), args.Error(1)
+}
+
+func  matchRequest(req *http.Request) bool {
+	pathOk := req.URL.Scheme+"://"+req.URL.Host+req.URL.Path == expectedAuthorizerUri
+	b,_:=ioutil.ReadAll(req.Body)
+	token := struct {
+		Token string
+	}{}
+	json.Unmarshal(b,&token)
+	tokenOk:= token.Token == expectedToken
+	return pathOk && tokenOk
+}
+
+func responseOk() (*http.Response, error) {
+	token := Token{Sub: "subject",AccessType: "read"}
+	b,_:=json.Marshal(&token)
+	r := ioutil.NopCloser(bytes.NewReader(b))
+	return &http.Response{
+		StatusCode: http.StatusOK,
+		Body:       r,
+	}, nil
+}
+
+func responseUnauth() (*http.Response, error) {
+	r := ioutil.NopCloser(bytes.NewReader([]byte("wrong JWT token")))
+	return &http.Response{
+		StatusCode: http.StatusUnauthorized,
+		Body:       r,
+	}, nil
+}
+
+func responseErr() (*http.Response, error) {
+	return &http.Response{}, errors.New("cannpt connect")
+}
+
+var authTests = []struct {
+	response func ()(*http.Response, error)
+	twice bool
+	ok bool
+	message string
+}{
+	{responseOk,false,true,"ok"},
+	{responseOk,true,true,"second time uses cache"},
+	{responseErr,false,false,"not auth"},
+	{responseUnauth,false,false,"request error"},
+}
+
+func TestAuthorize(t *testing.T) {
+	settings.AuthorizationServer = "authorizer:8400"
+	var client MockClient
+	auth = &AsapoAuthorizer{
+		serverUrl:  expectedAuthorizerUri,
+		httpClient: &client,
+	}
+	for _,test := range authTests {
+		client.On("Do",  mock.MatchedBy(matchRequest)).Once().Return(test.response())
+		token, err := auth.AuthorizeToken(expectedToken)
+		if test.twice {
+			token, err = auth.AuthorizeToken(expectedToken)
+		}
+		client.AssertExpectations(t)
+		client.ExpectedCalls = nil
+		if test.ok {
+			assert.Nil(t,err,test.message)
+			assert.Equal(t,"subject",token.Sub,test.message)
+			assert.Equal(t,"read",token.AccessType,test.message)
+		} else {
+			assert.NotNil(t,err,test.message)
+		}
+		delete(cachedTokens.tokens, expectedToken)
+	}
+
+}
+
diff --git a/broker/src/asapo_broker/server/process_request.go b/broker/src/asapo_broker/server/process_request.go
index 3e937b879ac297a709b962f6f5d96b597bb6d76a..b5b8e7dd602486fc14292c383b77ec52c15fd609 100644
--- a/broker/src/asapo_broker/server/process_request.go
+++ b/broker/src/asapo_broker/server/process_request.go
@@ -58,8 +58,8 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
 		return
 	}
 
-	if err := testAuth(r, db_name); err != nil {
-		writeAuthAnswer(w, "get "+op, db_name, err.Error())
+	if err := authorize(r, db_name); err != nil {
+		writeAuthAnswer(w, "get "+op, db_name, err)
 		return
 	}
 
diff --git a/broker/src/asapo_broker/server/process_request_test.go b/broker/src/asapo_broker/server/process_request_test.go
index b4967924720e52f8a431937d207f216687601171..ba9a23de59544b2f93a2411d790583ff55d9bcb0 100644
--- a/broker/src/asapo_broker/server/process_request_test.go
+++ b/broker/src/asapo_broker/server/process_request_test.go
@@ -23,17 +23,29 @@ const wrongGroupID = "_bid2a5auidddp1vl71"
 const expectedSource = "datasource"
 const expectedStream = "stream"
 
+type MockAuthServer struct {
+}
+
+func (a * MockAuthServer) AuthorizeToken(tokenJWT string) (token Token, err error) {
+	if tokenJWT =="ok" {
+		return Token{
+			Sub:        "bt_"+expectedBeamtimeId,
+			AccessType: "read",
+		},nil
+	} else {
+		return Token{},errors.New("wrong JWT token")
+	}
+}
+
+
 func prepareTestAuth() {
 	expectedBeamtimeId = "beamtime_id"
 	expectedDBName = expectedBeamtimeId + "_" + expectedSource
-	auth = utils.NewHMACAuth("secret")
-	token, err := auth.GenerateToken(&expectedBeamtimeId)
-	if err != nil {
-		panic(err)
-	}
-	correctTokenSuffix = "?token=" + token
+
+	auth = &MockAuthServer{}
+	correctTokenSuffix = "?token=ok"
 	wrongTokenSuffix = "?blablabla=aa"
-	suffixWithWrongToken = "?token=blabla"
+	suffixWithWrongToken = "?token=wrong"
 }
 
 type request struct {
@@ -107,7 +119,7 @@ func TestProcessRequestTestSuite(t *testing.T) {
 }
 
 func (suite *ProcessRequestTestSuite) TestProcessRequestWithWrongToken() {
-	logger.MockLog.On("Error", mock.MatchedBy(containsMatcher("wrong token")))
+	logger.MockLog.On("Error", mock.MatchedBy(containsMatcher("wrong JWT token")))
 
 	w := doRequest("/database/" + expectedBeamtimeId + "/" + expectedSource + "/" + expectedStream + "/" + expectedGroupID + "/next" + suffixWithWrongToken)
 
diff --git a/broker/src/asapo_broker/server/request_common.go b/broker/src/asapo_broker/server/request_common.go
index 28f2bc38d729c1cc14cafc6e696bdf71cfc9ccd8..6912523e8340282ca6bb82165e223c2a4859804d 100644
--- a/broker/src/asapo_broker/server/request_common.go
+++ b/broker/src/asapo_broker/server/request_common.go
@@ -2,16 +2,23 @@ package server
 
 import (
 	"asapo_common/logger"
+	"asapo_common/utils"
 	"errors"
 	"net/http"
 	"strconv"
 )
 
-func writeAuthAnswer(w http.ResponseWriter, requestName string, db_name string, err string) {
+func writeAuthAnswer(w http.ResponseWriter, requestName string, db_name string, err error) {
 	log_str := "processing " + requestName + " request in " + db_name + " at " + settings.GetDatabaseServer()
-	logger.Error(log_str + " - " + err)
-	w.WriteHeader(http.StatusUnauthorized)
-	w.Write([]byte(err))
+	logger.Error(log_str + " - " + err.Error())
+
+	httpError, ok := err.(*HttpError)
+	if ok && httpError.statusCode != http.StatusUnauthorized {
+		w.WriteHeader(http.StatusInternalServerError)
+	} else {
+		w.WriteHeader(http.StatusUnauthorized)
+	}
+	w.Write([]byte(err.Error()))
 }
 
 func valueTrue(r *http.Request, key string) bool {
@@ -39,22 +46,40 @@ func valueInt(r *http.Request, key string) int {
 	return i
 }
 
-func datasetRequested(r *http.Request) (bool,int) {
-	return valueTrue(r, "dataset"),valueInt(r,"minsize")
+func datasetRequested(r *http.Request) (bool, int) {
+	return valueTrue(r, "dataset"), valueInt(r, "minsize")
 }
 
-func testAuth(r *http.Request, beamtime_id string) error {
-	token_got := r.URL.Query().Get("token")
+func authorize(r *http.Request, beamtime_id string) error {
+	tokenJWT := r.URL.Query().Get("token")
 
-	if len(token_got) == 0 {
+	if len(tokenJWT) == 0 {
 		return errors.New("cannot extract token from request")
 	}
 
-	token_expect, _ := auth.GenerateToken(&beamtime_id)
+	token, err := auth.AuthorizeToken(tokenJWT)
+	if err != nil {
+		return err
+	}
+
+	err = checkSubject(token.Sub, beamtime_id)
+	if err != nil {
+		return err
+	}
+
+	return checkAccessType(token.AccessType)
+}
 
-	if token_got != token_expect {
-		return errors.New("wrong token")
+func checkSubject(subject string, beamtime_id string) error {
+	if subject != utils.SubjectFromBeamtime(beamtime_id) {
+		return errors.New("wrong token subject")
 	}
+	return nil
+}
 
+func checkAccessType(accessType string) error {
+	if accessType != "read" && accessType != "write" {
+		return errors.New("wrong token access type")
+	}
 	return nil
 }
diff --git a/broker/src/asapo_broker/server/server.go b/broker/src/asapo_broker/server/server.go
index 01bf25de7195193e46041c12e0d00b95f722bc42..c69d58e578ba85eeee96e31836cb5db26b533aab 100644
--- a/broker/src/asapo_broker/server/server.go
+++ b/broker/src/asapo_broker/server/server.go
@@ -3,39 +3,38 @@ package server
 import (
 	"asapo_broker/database"
 	log "asapo_common/logger"
-	"asapo_common/utils"
 	"errors"
 	"io/ioutil"
 	"net/http"
 )
 
-const  kDefaultresendInterval = 10
-const  kDefaultStreamCacheUpdateIntervalMs = 100
+const kDefaultresendInterval = 10
+const kDefaultStreamCacheUpdateIntervalMs = 100
 
 var db database.Agent
 
 type serverSettings struct {
-	DiscoveryServer     string
-	DatabaseServer      string
-	PerformanceDbServer string
-	PerformanceDbName   string
-	SecretFile          string
-	Port                int
-	LogLevel            string
-	discoveredDbAddress string
-	CheckResendInterval *int
+	DiscoveryServer             string
+	DatabaseServer              string
+	PerformanceDbServer         string
+	PerformanceDbName           string
+	AuthorizationServer         string
+	Port                        int
+	LogLevel                    string
+	discoveredDbAddress         string
+	CheckResendInterval         *int
 	StreamCacheUpdateIntervalMs *int
 }
 
 func (s *serverSettings) GetResendInterval() int {
-	if s.CheckResendInterval==nil {
+	if s.CheckResendInterval == nil {
 		return kDefaultresendInterval
 	}
 	return *s.CheckResendInterval
 }
 
 func (s *serverSettings) GetStreamCacheUpdateInterval() int {
-	if s.StreamCacheUpdateIntervalMs==nil {
+	if s.StreamCacheUpdateIntervalMs == nil {
 		return kDefaultStreamCacheUpdateIntervalMs
 	}
 	return *s.StreamCacheUpdateIntervalMs
@@ -51,7 +50,7 @@ func (s *serverSettings) GetDatabaseServer() string {
 
 var settings serverSettings
 var statistics serverStatistics
-var auth utils.Auth
+var auth Authorizer
 
 type discoveryAPI struct {
 	Client  *http.Client
@@ -91,7 +90,7 @@ func InitDB(dbAgent database.Agent) (err error) {
 		log.Debug("Got mongodb server: " + settings.discoveredDbAddress)
 	}
 
-	db.SetSettings(database.DBSettings{ReadFromInprocessPeriod: settings.GetResendInterval(),UpdateStreamCachePeriodMs: settings.GetStreamCacheUpdateInterval()})
+	db.SetSettings(database.DBSettings{ReadFromInprocessPeriod: settings.GetResendInterval(), UpdateStreamCachePeriodMs: settings.GetStreamCacheUpdateInterval()})
 
 	return db.Connect(settings.GetDatabaseServer())
 }
diff --git a/broker/src/asapo_broker/server/server_nottested.go b/broker/src/asapo_broker/server/server_nottested.go
index ffa4df68f9fab3e6fc40dbdbd68c66d8a43a4dc7..3f7cb0a746949205697741387c8e28e1d1402b61 100644
--- a/broker/src/asapo_broker/server/server_nottested.go
+++ b/broker/src/asapo_broker/server/server_nottested.go
@@ -24,12 +24,8 @@ func Start() {
 	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(settings.Port), http.HandlerFunc(mux.ServeHTTP)))
 }
 
-func createAuth() (utils.Auth, error) {
-	secret, err := utils.ReadFirstStringFromFile(settings.SecretFile)
-	if err != nil {
-		return nil, err
-	}
-	return utils.NewHMACAuth(secret), nil
+func createAuth() Authorizer {
+	return &AsapoAuthorizer{settings.AuthorizationServer,&http.Client{}}
 }
 
 func ReadConfig(fname string) (log.Level, error) {
@@ -61,17 +57,11 @@ func ReadConfig(fname string) (log.Level, error) {
 		return log.FatalLevel, errors.New("PerformanceDbName not set")
 	}
 
-	if settings.SecretFile == "" {
-		return log.FatalLevel, errors.New("Secret file not set")
-	}
-
-	var err error
-	auth, err = createAuth()
-	if err != nil {
-		return log.FatalLevel, err
+	if settings.AuthorizationServer == "" {
+		return log.FatalLevel, errors.New("AuthorizationServer not set")
 	}
 
-	level, err := log.LevelFromString(settings.LogLevel)
+	auth = createAuth()
 
-	return level, err
+	return log.LevelFromString(settings.LogLevel)
 }
diff --git a/common/go/src/asapo_common/go.mod b/common/go/src/asapo_common/go.mod
index ae7d8cf1e05a99c0ed5c8dc2d5383e570f58ca86..31eee8613f224bc7425474074f9199044934a36c 100644
--- a/common/go/src/asapo_common/go.mod
+++ b/common/go/src/asapo_common/go.mod
@@ -1,3 +1,10 @@
 module asapo_common
 
-go 1.14
+go 1.16
+
+require (
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible
+	github.com/gorilla/mux v1.8.0
+	github.com/sirupsen/logrus v1.8.0
+	github.com/stretchr/testify v1.7.0
+)
diff --git a/common/go/src/asapo_common/go.sum b/common/go/src/asapo_common/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..6f35f25f5853eb59ed8eb5b781b6410839850826
--- /dev/null
+++ b/common/go/src/asapo_common/go.sum
@@ -0,0 +1,24 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/common/go/src/asapo_common/structs/structs.go b/common/go/src/asapo_common/structs/structs.go
new file mode 100644
index 0000000000000000000000000000000000000000..07d8fb6d28f8e5c88ce8052ef30fbb3fb8cbb198
--- /dev/null
+++ b/common/go/src/asapo_common/structs/structs.go
@@ -0,0 +1,31 @@
+package structs
+
+type FolderTokenTokenExtraClaim struct {
+	RootFolder string
+}
+
+type AccessTokenExtraClaim struct {
+	AccessType string
+}
+
+type IntrospectTokenRequest struct {
+	Token      string
+}
+
+type IntrospectTokenResponse struct {
+	Sub        string
+	AccessType string
+}
+
+type IssueTokenRequest struct {
+	Subject    map[string]string
+	DaysValid  int
+	AccessType string
+}
+
+type IssueTokenResponse struct {
+	Token      string
+	Sub        string
+	AccessType string
+	Expires    string
+}
diff --git a/common/go/src/asapo_common/utils/authorization.go b/common/go/src/asapo_common/utils/authorization.go
index aac273c5a213b2fd79abe03a55e025a37c666523..c913611730477d2611c0e6410a77bbf25e72f05b 100644
--- a/common/go/src/asapo_common/utils/authorization.go
+++ b/common/go/src/asapo_common/utils/authorization.go
@@ -13,23 +13,19 @@ import (
 	"time"
 )
 
-type AuthorizationRequest struct {
-	Token   string
-	Command string
-	URL     string
+type Auth interface {
+	GenerateToken(...interface{}) (string, error)
+	ProcessAuth(http.HandlerFunc, string) http.HandlerFunc
+	Name() string
+	CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (string,error)
 }
 
-type AuthorizationResponce struct {
-	Status       int
-	StatusText   string
-	UserName     string
-	Token        string
-	ValidityTime int
+func SubjectFromBeamtime(bt string)string {
+	return "bt_"+bt
 }
 
-type Auth interface {
-	GenerateToken(...interface{}) (string, error)
-	Name() string
+func SubjectFromBeamline(bl string)string {
+	return "bl_"+bl
 }
 
 
@@ -79,10 +75,15 @@ func ExtractAuthInfo(r *http.Request) (authType, token string, err error) {
 
 type CustomClaims struct {
 	jwt.StandardClaims
-	Duration    time.Duration
 	ExtraClaims interface{}
 }
 
+func (claim *CustomClaims) SetExpiration(duration time.Duration){
+	if duration > 0 {
+		claim.ExpiresAt = time.Now().Add(duration).Unix()
+	}
+}
+
 type JWTAuth struct {
 	Key string
 }
@@ -101,10 +102,6 @@ func (t JWTAuth) GenerateToken(val ...interface{}) (string, error) {
 		return "", errors.New("Wrong claims")
 	}
 
-	if claims.Duration > 0 {
-		claims.ExpiresAt = time.Now().Add(claims.Duration).Unix()
-	}
-
 	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
 	tokenString, err := token.SignedString([]byte(t.Key))
 
@@ -115,6 +112,11 @@ func (t JWTAuth) GenerateToken(val ...interface{}) (string, error) {
 	return tokenString, nil
 }
 
+func (a *JWTAuth)ProcessAuth(fn http.HandlerFunc, payload string) http.HandlerFunc {
+	// payload ignored
+	return ProcessJWTAuth(fn,a.Key)
+}
+
 func ProcessJWTAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		if (r.RequestURI == "/health-check") { // always allow /health-check request
@@ -132,7 +134,7 @@ func ProcessJWTAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
 
 		if authType == "Bearer" {
 			if claims, ok := CheckJWTToken(token, key); !ok {
-				http.Error(w, "Authorization error - tocken does not match", http.StatusUnauthorized)
+				http.Error(w, "Authorization error - token does not match", http.StatusUnauthorized)
 				return
 			} else {
 				ctx = context.WithValue(ctx, "TokenClaims", claims)
@@ -145,6 +147,26 @@ func ProcessJWTAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
 	}
 }
 
+func (a *JWTAuth) CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (subject string,err error) {
+	// payload ignored
+	c, ok := CheckJWTToken(token,a.Key)
+	if !ok {
+		return "",errors.New("wrong JWT token")
+	}
+	claim,ok  := c.(*CustomClaims)
+	if !ok {
+		return "",errors.New("cannot get CustomClaims")
+	}
+
+	subject = claim.Subject
+
+	if extraClaims!=nil {
+		err = MapToStruct(claim.ExtraClaims.(map[string]interface{}), extraClaims)
+	}
+	return subject,err
+}
+
+
 func CheckJWTToken(token, key string) (jwt.Claims, bool) {
 
 	if token == "" {
@@ -162,14 +184,21 @@ func CheckJWTToken(token, key string) (jwt.Claims, bool) {
 	return nil, false
 }
 
-func JobClaimFromContext(r *http.Request, val interface{}) error {
+func JobClaimFromContext(r *http.Request, customClaim **CustomClaims, val interface{}) error {
 	c := r.Context().Value("TokenClaims")
 
 	if c == nil {
 		return errors.New("Empty context")
 	}
 
-	claim := c.(*CustomClaims)
+	claim,ok  := c.(*CustomClaims)
+	if !ok {
+		return errors.New("cannot get CustomClaims")
+	}
+
+	if customClaim!=nil {
+		*customClaim = claim
+	}
 
 	return MapToStruct(claim.ExtraClaims.(map[string]interface{}), val)
 }
@@ -184,7 +213,7 @@ func NewHMACAuth(key string) *HMACAuth {
 }
 
 func (a *HMACAuth) Name() string {
-	return "Bearer"
+	return "HMAC-SHA-256"
 }
 
 
@@ -209,7 +238,11 @@ func (h HMACAuth) GenerateToken(val ...interface{}) (string, error) {
 	return sha, nil
 }
 
-func ProcessHMACAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
+func (a *HMACAuth)ProcessAuth(fn http.HandlerFunc, payload string) http.HandlerFunc {
+	return ProcessHMACAuth(fn,payload,a.Key)
+}
+
+func ProcessHMACAuth(fn http.HandlerFunc, payload, key string) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 
 		authType, token, err := ExtractAuthInfo(r)
@@ -218,11 +251,9 @@ func ProcessHMACAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
 			http.Error(w, err.Error(), http.StatusUnauthorized)
 			return
 		}
-	// todo extract beamline from request
-		value := "beamline"
 		if authType == "HMAC-SHA-256" {
-			if !CheckHMACToken(value, token, key) {
-				http.Error(w, "Internal authorization error - tocken does not match", http.StatusUnauthorized)
+			if !CheckHMACToken(payload, token, key) {
+				http.Error(w, "Internal authorization error - token does not match", http.StatusUnauthorized)
 				return
 			}
 		} else {
@@ -233,6 +264,23 @@ func ProcessHMACAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
 	}
 }
 
+func (a *HMACAuth) CheckAndGetContent(token string, _ interface{}, payload ...interface{}) (string,error) {
+	if len(payload) != 1 {
+		return "",errors.New("wrong payload")
+	}
+	value, ok := payload[0].(string)
+	if !ok {
+		return "",errors.New("wrong payload")
+	}
+
+	ok = CheckHMACToken(token,value,a.Key)
+	if !ok {
+		return "",errors.New("wrong HMAC token")
+	}
+	return value,nil
+
+}
+
 func CheckHMACToken(value string, token, key string) bool {
 
 	if token == "" {
diff --git a/common/go/src/asapo_common/utils/authorization_test.go b/common/go/src/asapo_common/utils/authorization_test.go
index d8a9b47745443a470d52051d73e2de11d36ab94d..cda7f43b091bfba5dc5f8228199e6ae125f01933 100644
--- a/common/go/src/asapo_common/utils/authorization_test.go
+++ b/common/go/src/asapo_common/utils/authorization_test.go
@@ -8,8 +8,16 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
+type authorizationResponse struct {
+	Status       int
+	StatusText   string
+	UserName     string
+	Token        string
+	ValidityTime int
+}
+
 type JobClaim struct {
-	AuthorizationResponce
+	authorizationResponse
 	JobInd string
 }
 
@@ -17,7 +25,7 @@ type JobClaim struct {
 func writeAuthResponse(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusOK)
 	var jc JobClaim
-	JobClaimFromContext(r, &jc)
+	JobClaimFromContext(r,nil,&jc)
 	w.Write([]byte(jc.UserName))
 	w.Write([]byte(jc.JobInd))
 }
@@ -25,14 +33,15 @@ func writeAuthResponse(w http.ResponseWriter, r *http.Request) {
 func TestGenerateJWTToken(t *testing.T) {
 
 	a := NewJWTAuth("hi")
-	token, _ := a.GenerateToken((&CustomClaims{Duration: 0, ExtraClaims: nil}))
-	assert.Equal(t, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJEdXJhdGlvbiI"+
-		"6MCwiRXh0cmFDbGFpbXMiOm51bGx9.JJcqNZciIDILk-A2sJZCY1sND458bcjNv6tXC2jxric",
+	cc := CustomClaims{ExtraClaims: nil}
+	cc.SetExpiration(0)
+	token, _ := a.GenerateToken((&cc))
+	assert.Equal(t, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJFeHRyYUNsYWltcyI6bnVsbH0.QXaiODT7V1tEwmVKCLfpH2WbgjNJpqJcNgeVivFm7GY",
 		token, "jwt token")
 
 }
 
-var HJWTAuthtests = []struct {
+var JWTAuthtests = []struct {
 	Mode       string
 	Key        string
 	User       string
@@ -49,7 +58,7 @@ var HJWTAuthtests = []struct {
 }
 
 func TestProcessJWTAuth(t *testing.T) {
-	for _, test := range HJWTAuthtests {
+	for _, test := range JWTAuthtests {
 		req, _ := http.NewRequest("POST", "http://blabla", nil)
 
 		var claim JobClaim
@@ -58,7 +67,9 @@ func TestProcessJWTAuth(t *testing.T) {
 
 		a := NewJWTAuth(test.Key)
 
-		token, _ := a.GenerateToken((&CustomClaims{Duration: test.Duration, ExtraClaims: &claim}))
+		cc:= CustomClaims{ExtraClaims: &claim}
+		cc.SetExpiration(test.Duration)
+		token, _ := a.GenerateToken((&cc))
 		if test.Mode == "header" {
 			req.Header.Add("Authorization", "Bearer "+token)
 		}
diff --git a/common/go/src/asapo_common/utils/structs.go b/common/go/src/asapo_common/utils/structs.go
deleted file mode 100644
index 37f7a1f567f2f39b8ff953d8796a19d1e6e8f1bc..0000000000000000000000000000000000000000
--- a/common/go/src/asapo_common/utils/structs.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package utils
-
-type FolderTokenTokenExtraClaim struct {
-	RootFolder string
-}
diff --git a/config/nomad/authorizer.nmd.in b/config/nomad/authorizer.nmd.in
index dfd6072465d23f6deff1ba2b1b5694f6c6030be5..7fd1366679d2a9bc8770f5df2c220e146aed9a46 100644
--- a/config/nomad/authorizer.nmd.in
+++ b/config/nomad/authorizer.nmd.in
@@ -50,6 +50,13 @@ job "authorizer" {
          change_mode   = "signal"
          change_signal = "SIGHUP"
       }
+      template {
+         source        = "@WORK_DIR@/auth_secret_admin.key"
+         destination   = "auth_secret_admin.key"
+         change_mode   = "signal"
+         change_signal = "SIGHUP"
+      }
+
     }
   }
 }
diff --git a/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json b/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
index 76d3a8480012356fccf9daa46e676e6595b00ca4..5225327c48c0208094f1bd8906975e8723c0f09e 100644
--- a/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
+++ b/deploy/asapo_helm_chart/asapo/configs/asapo-authorizer.json
@@ -6,7 +6,8 @@
   {"beamtimeId":"asapo_test2","beamline":"test2","core-path":"{{ .Values.common.offlineDir }}/test_facility/gpfs/test2/2019/data/asapo_test2"}],
   "RootBeamtimesFolder":"{{ .Values.common.offlineDir }}",
   "CurrentBeamlinesFolder":"{{ .Values.common.onlineDir }}",
-  "SecretFile":"/etc/authorizer/auth_secret.key",
+  "UserSecretFile":"/etc/authorizer/auth_secret.key",
+  "AdminSecretFile":"/etc/authorizer/auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
   {
diff --git a/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json b/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json
index 63452b6f31afeef34bfcdb1f8c6a3f74fc4c77b5..00325d3e1b8a514c42ad8a72acc816ea52a6e909 100644
--- a/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json
+++ b/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json
@@ -1,10 +1,10 @@
 {
   "DatabaseServer":"asapo-mongodb:{{ .Values.ownServices.mongodb.port }}",
   "DiscoveryServer": "asapo-discovery:{{ .Values.ownServices.discovery.port }}",
+  "AuthorizationServer": "asapo-authorizer:{{ .Values.ownServices.authorization.port }}",
   "PerformanceDbServer":"{{ .Chart.Name }}-influxdb:{{ .Values.influxdb.influxdb.service.port }}",
   "PerformanceDbName": "asapo_brokers",
   "Port": {{ .Values.ownServices.broker.port }},
   "CheckResendInterval":10,
-  "LogLevel":"debug",
-  "SecretFile":"/etc/broker/auth_secret.key"
+  "LogLevel":"debug"
 }
diff --git a/deploy/asapo_helm_chart/asapo/templates/auth-secret-admin.yaml b/deploy/asapo_helm_chart/asapo/templates/auth-secret-admin.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0a6b49b7922e3ef2c59a542498b267b14b8aebe5
--- /dev/null
+++ b/deploy/asapo_helm_chart/asapo/templates/auth-secret-admin.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: auth-secret-admin
+type: Opaque
+data:
+  auth_secret_admin.key: {{ .Values.common.authSecretAdmin | b64enc | quote }}
diff --git a/deploy/asapo_helm_chart/asapo/templates/authorizer-deployment.yaml b/deploy/asapo_helm_chart/asapo/templates/authorizer-deployment.yaml
index e923be6acd41da528beaf088b8852125d3b8cf55..100e114d5a5980a0c42ef64807e75e8d8fb2a48c 100644
--- a/deploy/asapo_helm_chart/asapo/templates/authorizer-deployment.yaml
+++ b/deploy/asapo_helm_chart/asapo/templates/authorizer-deployment.yaml
@@ -16,6 +16,7 @@ spec:
       annotations:
         checksum/config: {{ .Files.Get "configs/asapo-authorizer.json" | sha256sum  }}
         checksum/secret: {{ include (print $.Template.BasePath "/auth-secret.yaml") . | sha256sum }}
+        checksum/secret-admin: {{ include (print $.Template.BasePath "/auth-secret-admin.yaml") . | sha256sum }}
         checksum/fluentd-config: {{ .Files.Get "configs/asapo-fluentd.conf" | sha256sum  }}
     spec:
       volumes:
@@ -26,6 +27,8 @@ spec:
                   name: asapo-authorizer-config
               - secret:
                   name: auth-secret
+              - secret:
+                  name: auth-secret-admin
         - name: shared-volume-offline
           persistentVolumeClaim:
             claimName: asapo-offline-pv
diff --git a/deploy/asapo_helm_chart/asapo/values.yaml b/deploy/asapo_helm_chart/asapo/values.yaml
index cfb5e3657d3b5627d0b562d2649f5397da687709..beccb7c2193ae10139e8325d3aa9ac175901bea3 100644
--- a/deploy/asapo_helm_chart/asapo/values.yaml
+++ b/deploy/asapo_helm_chart/asapo/values.yaml
@@ -55,6 +55,7 @@ ownServices:
 
 common:
   authSecret: "12ljzgneasfd"
+  authSecretAdmin: "12ljzgneasf123d"
   offlineDir: "/test_offline"
   onlineDir: "/test_online"
   asapoVersionTag: "develop"
diff --git a/deploy/asapo_services/scripts/asapo-services.nmd.tpl b/deploy/asapo_services/scripts/asapo-services.nmd.tpl
index dae2350c53835c4a4aed16d239a90fb81a8838f9..6220ae11d82341f7b997f0b11aa872908f5bbfe1 100644
--- a/deploy/asapo_services/scripts/asapo-services.nmd.tpl
+++ b/deploy/asapo_services/scripts/asapo-services.nmd.tpl
@@ -78,6 +78,11 @@ job "asapo-services" {
         destination   = "local/secret.key"
         change_mode   = "restart"
       }
+      template {
+        source        = "${scripts_dir}/auth_secret_admin.key"
+        destination   = "local/secret_admin.key"
+        change_mode   = "restart"
+      }
    }
   } #authorizer
   group "asapo-discovery" {
diff --git a/deploy/asapo_services/scripts/auth_secret_admin.key b/deploy/asapo_services/scripts/auth_secret_admin.key
new file mode 100644
index 0000000000000000000000000000000000000000..295004c5898aa11fe557d7178e073eef2a8606ec
--- /dev/null
+++ b/deploy/asapo_services/scripts/auth_secret_admin.key
@@ -0,0 +1 @@
+sfdskln123_w
\ No newline at end of file
diff --git a/deploy/asapo_services/scripts/authorizer.json.tpl b/deploy/asapo_services/scripts/authorizer.json.tpl
index e73af4ae5dc891ba81098ee47a31a09bb7481f1d..dc556433b469725f6b8e9e1917fb47c67a539adb 100644
--- a/deploy/asapo_services/scripts/authorizer.json.tpl
+++ b/deploy/asapo_services/scripts/authorizer.json.tpl
@@ -6,7 +6,8 @@
   {"beamtimeId":"asapo_test2","beamline":"test2","core-path":"{{ env "NOMAD_META_offline_dir" }}/test_facility/gpfs/test2/2019/data/asapo_test2"}],
   "RootBeamtimesFolder":"{{ env "NOMAD_META_offline_dir" }}",
   "CurrentBeamlinesFolder":"{{ env "NOMAD_META_online_dir" }}",
-  "SecretFile":"/local/secret.key",
+  "UserSecretFile":"/local/secret.key",
+  "AdminSecretFile":"/local/secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
     {
diff --git a/deploy/asapo_services/scripts/broker.json.tpl b/deploy/asapo_services/scripts/broker.json.tpl
index 9b0f75f1e72f49db9ae54c8e3e85250466b58ed2..bbd97f4218f30116f62aaab2ee94088f65b6a8e8 100644
--- a/deploy/asapo_services/scripts/broker.json.tpl
+++ b/deploy/asapo_services/scripts/broker.json.tpl
@@ -1,10 +1,10 @@
 {
   "DatabaseServer":"auto",
   "DiscoveryServer": "localhost:8400/asapo-discovery",
+  "AuthorizationServer": "localhost:8400/asapo-authorizer",
   "PerformanceDbServer":"localhost:8400/influxdb",
   "CheckResendInterval":10,
   "PerformanceDbName": "asapo_brokers",
   "Port":{{ env "NOMAD_PORT_broker" }},
-  "LogLevel":"info",
-  "SecretFile":"/local/secret.key"
+  "LogLevel":"info"
 }
diff --git a/discovery/src/asapo_discovery/go.mod b/discovery/src/asapo_discovery/go.mod
index 8661775101cee70211a111c2fb3bcf48bfb8f7c8..84dadee21b1e443654a1c9aaab81842c20e29eb6 100644
--- a/discovery/src/asapo_discovery/go.mod
+++ b/discovery/src/asapo_discovery/go.mod
@@ -1,16 +1,13 @@
 module asapo_discovery
 
-go 1.14
+go 1.16
 
 replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common
 
 require (
 	asapo_common v0.0.0
-	github.com/gorilla/mux v1.7.4 // indirect
 	github.com/hashicorp/consul/api v1.4.0
-	github.com/sirupsen/logrus v1.5.0 // indirect
-	github.com/stretchr/testify v1.4.0
-	k8s.io/api v0.17.0
+	github.com/stretchr/testify v1.7.0
 	k8s.io/apimachinery v0.17.0
 	k8s.io/client-go v0.17.0
 )
diff --git a/discovery/src/asapo_discovery/go.sum b/discovery/src/asapo_discovery/go.sum
index 859f1d959eb69a677e2ca214af6b005bd2a89e43..5b43fcb6be3e5b43431604d61ffe18ac5821eb4a 100644
--- a/discovery/src/asapo_discovery/go.sum
+++ b/discovery/src/asapo_discovery/go.sum
@@ -22,12 +22,10 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v1.0.2 h1:KPldsxuKGsS2FPWsNeg9ZO18aCrGKujPoWXn2yo+KQM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
-github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -42,8 +40,6 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA
 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
 github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
 github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -53,30 +49,29 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
-github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
-github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
-github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
-github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/hashicorp/consul v1.7.2 h1:pDEnRiUE8jOUlxIqzo8Jw3Zcsz6KSpygk2BjkrsASsk=
 github.com/hashicorp/consul/api v1.4.0 h1:jfESivXnO5uLdH650JU/6AnjRoHrLhULq0FnC3Kp9EY=
 github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
+github.com/hashicorp/consul/sdk v0.4.0 h1:zBtCfKJZcJDBvSCkQJch4ulp59m1rATFLKwNo/LYY30=
 github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
 github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
@@ -84,13 +79,17 @@ github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tk
 github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
 github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
 github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
 github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
 github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
 github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
 github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -98,26 +97,27 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
 github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
-github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
 github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
 github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@@ -128,10 +128,12 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
@@ -150,20 +152,22 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
-github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -173,12 +177,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -202,8 +206,6 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -217,10 +219,8 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
@@ -233,8 +233,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -244,6 +242,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -251,6 +250,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -261,37 +261,24 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM=
 k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
-k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ=
-k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
 k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo=
 k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
-k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
-k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
 k8s.io/client-go v0.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg=
 k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
-k8s.io/client-go v1.5.1 h1:XaX/lo2/u3/pmFau8HN+sB5C/b4dc4Dmm2eXjBH4p1E=
-k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=
-k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
 k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
 k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
 k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-k8s.io/utils v0.0.0-20200327001022-6496210b90e8 h1:6JFbaLjRyBz8K2Jvt+pcT+N3vvwMZfg8MfVENwe9aag=
-k8s.io/utils v0.0.0-20200327001022-6496210b90e8/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
-sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
-sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
-sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
 sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
-sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
-sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/examples/consumer/getnext/check_linux.sh b/examples/consumer/getnext/check_linux.sh
index 21c2bf6842cd9a06edd94e70c5d02a826b99e4f6..049a9c4c9fa9e242990937d1759924b1936400c5 100644
--- a/examples/consumer/getnext/check_linux.sh
+++ b/examples/consumer/getnext/check_linux.sh
@@ -4,7 +4,7 @@ source_path=dummy
 beamtime_id=test_run
 data_source=detector
 database_name=${beamtime_id}_${data_source}
-token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 set -e
 
@@ -15,12 +15,14 @@ Cleanup() {
     nomad stop nginx
     nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
     nomad stop discovery
+    nomad stop authorizer
     nomad stop broker
 	echo "db.dropDatabase()" | mongo ${database_name}
 }
 
 nomad run nginx.nmd
 nomad run discovery.nmd
+nomad run authorizer.nmd
 nomad run broker.nmd
 
 for i in `seq 1 3`;
diff --git a/examples/consumer/getnext/check_windows.bat b/examples/consumer/getnext/check_windows.bat
index 62b2600c6aaa80f1b4f4e794f1fbc5e7fedc04f0..b9cc3044bfeed8936605ead243ef803d020f358b 100644
--- a/examples/consumer/getnext/check_windows.bat
+++ b/examples/consumer/getnext/check_windows.bat
@@ -5,7 +5,7 @@ SET data_source=detector
 SET database_name=%beamtime_id%_%data_source%
 
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
-set token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+set token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 call start_services.bat
 
diff --git a/examples/consumer/getnext_python/check_linux.sh b/examples/consumer/getnext_python/check_linux.sh
index a600692a552c9aa11c75ba0030af91dcaec41e1a..2ac44afddabac4641741cbb6214294b0500eff2b 100644
--- a/examples/consumer/getnext_python/check_linux.sh
+++ b/examples/consumer/getnext_python/check_linux.sh
@@ -4,7 +4,7 @@ source_path=dummy
 beamtime_id=test_run
 data_source=detector
 database_name=${beamtime_id}_${data_source}
-token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 group_id=bif31l2uiddd4r0q6b40
 set -e
 
@@ -15,12 +15,14 @@ Cleanup() {
     nomad stop nginx
     nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
     nomad stop discovery
+    nomad stop authorizer
     nomad stop broker
 	echo "db.dropDatabase()" | mongo ${database_name}
 }
 
 nomad run nginx.nmd
 nomad run discovery.nmd
+nomad run authorizer.nmd
 nomad run broker.nmd
 
 for i in `seq 1 3`;
diff --git a/examples/consumer/getnext_python/check_windows.bat b/examples/consumer/getnext_python/check_windows.bat
index c546f6108686ab0f4ca55632d599f2711e222e3f..448e1c2652f18e99c1772b6289e96b7d35528fac 100644
--- a/examples/consumer/getnext_python/check_windows.bat
+++ b/examples/consumer/getnext_python/check_windows.bat
@@ -4,7 +4,7 @@ SET data_source=detector
 SET database_name=%beamtime_id%_%data_source%
 
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
-set token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+set token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 set group_id=bif31l2uiddd4r0q6b40
 
 call start_services.bat
diff --git a/examples/pipeline/in_to_out/check_linux.sh b/examples/pipeline/in_to_out/check_linux.sh
index 8540d411d14f789d3902a71f2ace9a24c4c5b1d8..f6d5943a0d93574102deec221547cf7451880b27 100644
--- a/examples/pipeline/in_to_out/check_linux.sh
+++ b/examples/pipeline/in_to_out/check_linux.sh
@@ -10,7 +10,8 @@ indatabase_name=${beamtime_id}_${data_source_in}
 outdatabase_name=${beamtime_id}_${data_source_out}
 outdatabase_name2=${beamtime_id}_${data_source_out2}
 
-token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+#asapo_test read token
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 beamline=test
 receiver_root_folder=/tmp/asapo/receiver/files
diff --git a/examples/pipeline/in_to_out/check_windows.bat b/examples/pipeline/in_to_out/check_windows.bat
index 5b0f9bb514ae45e2f867a6e88debf5e3ab4c2856..f464ea5d8e57679a00d1e9e26eee791c35eba1b6 100644
--- a/examples/pipeline/in_to_out/check_windows.bat
+++ b/examples/pipeline/in_to_out/check_windows.bat
@@ -8,7 +8,7 @@ SET indatabase_name=%beamtime_id%_%data_source_in%
 SET outdatabase_name=%beamtime_id%_%data_source_out%
 SET outdatabase_name2=%beamtime_id%_%data_source_out2%
 
-SET token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+SET token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 SET beamline=test
 
diff --git a/examples/pipeline/in_to_out_python/check_linux.sh b/examples/pipeline/in_to_out_python/check_linux.sh
index 444c6ceeac2c5783d5611cd4490eb768b9702ad8..7da5ccf9a86560ece423d16d8133a8dd397d468f 100644
--- a/examples/pipeline/in_to_out_python/check_linux.sh
+++ b/examples/pipeline/in_to_out_python/check_linux.sh
@@ -12,7 +12,8 @@ nthreads=4
 indatabase_name=${beamtime_id}_${data_source_in}
 outdatabase_name=${beamtime_id}_${data_source_out}
 
-token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+#asapo_test read token
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 beamline=test
 receiver_root_folder=/tmp/asapo/receiver/files
diff --git a/examples/pipeline/in_to_out_python/check_windows.bat b/examples/pipeline/in_to_out_python/check_windows.bat
index 3160af194c3d56c15a3c943700d2541e1bb2c896..de9982180aead654ea7db9f85a3ea15b1fcbc890 100644
--- a/examples/pipeline/in_to_out_python/check_windows.bat
+++ b/examples/pipeline/in_to_out_python/check_windows.bat
@@ -6,7 +6,7 @@ SET data_source_out=simulation
 SET indatabase_name=%beamtime_id%_%data_source_in%
 SET outdatabase_name=%beamtime_id%_%data_source_out%
 
-SET token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+SET token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 SET beamline=test
 
diff --git a/file_transfer/CMakeLists.txt b/file_transfer/CMakeLists.txt
index 9dee3c150e8b12f1fa60d089dbb29b7d02d04196..b6d2875b165ad833c414930f1f59faf9000b2ab4 100644
--- a/file_transfer/CMakeLists.txt
+++ b/file_transfer/CMakeLists.txt
@@ -1,20 +1,8 @@
 set (TARGET_NAME asapo-file-transfer)
 
-if (NOT "$ENV{GOPATH}" STREQUAL "")
-	set(GOPATH $ENV{GOPATH})
-endif()
-
-if (NOT GOPATH)
-    message (FATAL_ERROR "GOPATH not set")
-endif()
-
-message(STATUS "global gopath ${GOPATH}")
-
 IF(WIN32)
-    set (gopath "${GOPATH}\;${CMAKE_CURRENT_SOURCE_DIR}\;${CMAKE_SOURCE_DIR}/common/go")
     set (exe_name "${TARGET_NAME}.exe")
 ELSE()
-    set (gopath ${GOPATH}:${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_SOURCE_DIR}/common/go)
     set (exe_name "${TARGET_NAME}")
 ENDIF()
 
@@ -23,8 +11,8 @@ include(testing_go)
 configure_file(docker/Dockerfile . COPYONLY)
 
 add_custom_target(asapo-file-transfer ALL
-    COMMAND  ${CMAKE_COMMAND} -E env GOPATH=${gopath}
-    go build ${GO_OPTS} -o ${exe_name} asapo_file_transfer/main
+    COMMAND go build ${GO_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} main/file_transfer.go
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_file_transfer
     VERBATIM)
 define_property(TARGET PROPERTY EXENAME
         BRIEF_DOCS <executable name>
@@ -32,4 +20,4 @@ define_property(TARGET PROPERTY EXENAME
 
 set_target_properties(asapo-file-transfer PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name})
 
-gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}" "./...")
+gotest(${TARGET_NAME}  "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_file_transfer" "./...")
diff --git a/file_transfer/src/asapo_file_transfer/go.mod b/file_transfer/src/asapo_file_transfer/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..f7d1e31423978ab00347ff894ead26751d5a81a0
--- /dev/null
+++ b/file_transfer/src/asapo_file_transfer/go.mod
@@ -0,0 +1,13 @@
+module asapo_file_transfer
+
+go 1.16
+
+replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common
+
+require (
+	asapo_common v0.0.0
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/sirupsen/logrus v1.8.0 // indirect
+	github.com/stretchr/testify v1.7.0
+)
diff --git a/file_transfer/src/asapo_file_transfer/go.sum b/file_transfer/src/asapo_file_transfer/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..6f35f25f5853eb59ed8eb5b781b6410839850826
--- /dev/null
+++ b/file_transfer/src/asapo_file_transfer/go.sum
@@ -0,0 +1,24 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/file_transfer/src/asapo_file_transfer/server/transfer.go b/file_transfer/src/asapo_file_transfer/server/transfer.go
index 9d7b76a0f5b201fabd9f30bec26dff10803ea7bd..18b172a8e232472bfb55495f0d88886b2e43d733 100644
--- a/file_transfer/src/asapo_file_transfer/server/transfer.go
+++ b/file_transfer/src/asapo_file_transfer/server/transfer.go
@@ -2,6 +2,7 @@ package server
 
 import (
 	log "asapo_common/logger"
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"encoding/json"
 	"errors"
@@ -24,8 +25,8 @@ func Exists(name string) bool {
 
 
 func checkClaim(r *http.Request,request* fileTransferRequest) (int,error) {
-	var extraClaim utils.FolderTokenTokenExtraClaim
-	if err := utils.JobClaimFromContext(r, &extraClaim); err != nil {
+	var extraClaim structs.FolderTokenTokenExtraClaim
+	if err := utils.JobClaimFromContext(r, nil, &extraClaim); err != nil {
 		return http.StatusInternalServerError,err
 	}
 	if extraClaim.RootFolder!=request.Folder {
diff --git a/file_transfer/src/asapo_file_transfer/server/transfer_test.go b/file_transfer/src/asapo_file_transfer/server/transfer_test.go
index 68be2f18dfa761419445c73bd02499a49c8184b5..815d4b48a0b7408f43c45c39e777b835f8bd95ee 100644
--- a/file_transfer/src/asapo_file_transfer/server/transfer_test.go
+++ b/file_transfer/src/asapo_file_transfer/server/transfer_test.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"asapo_common/structs"
 	"asapo_common/utils"
 	"github.com/stretchr/testify/assert"
 	"net/http"
@@ -34,10 +35,10 @@ func prepareToken(folder string) string{
 	auth := utils.NewJWTAuth("key")
 
 	var claims utils.CustomClaims
-	var extraClaim utils.FolderTokenTokenExtraClaim
+	var extraClaim structs.FolderTokenTokenExtraClaim
 	extraClaim.RootFolder = folder
 	claims.ExtraClaims = &extraClaim
-	claims.Duration = time.Duration(1) * time.Minute
+	claims.SetExpiration(time.Duration(1) * time.Minute)
 	token,_ := auth.GenerateToken(&claims)
 	return token
 }
diff --git a/producer/api/cpp/src/request_handler_tcp.cpp b/producer/api/cpp/src/request_handler_tcp.cpp
index 157c1212e6b24089d7ed8ace19d7de3f2fc26da5..e6f105d0150499ad74f665b16610710c97153df0 100644
--- a/producer/api/cpp/src/request_handler_tcp.cpp
+++ b/producer/api/cpp/src/request_handler_tcp.cpp
@@ -13,12 +13,18 @@ RequestHandlerTcp::RequestHandlerTcp(ReceiverDiscoveryService* discovery_service
 }
 
 Error RequestHandlerTcp::Authorize(const std::string& source_credentials) {
-    GenericRequestHeader header{kOpcodeAuthorize, 0, 0, 0, source_credentials.c_str()};
+    GenericRequestHeader header{kOpcodeAuthorize, 0, 0, source_credentials.size(), ""};
     Error err;
     io__->Send(sd_, &header, sizeof(header), &err);
     if(err) {
         return err;
     }
+
+    io__->Send(sd_, (void*) source_credentials.c_str(), (size_t) header.meta_size, &err);
+    if (err) {
+        return err;
+    }
+
     return ReceiveResponse(header, nullptr);
 }
 
diff --git a/producer/api/cpp/unittests/test_request_handler_tcp.cpp b/producer/api/cpp/unittests/test_request_handler_tcp.cpp
index 25a88248bb4b2b3ed107704870670260d9a1699e..536aee478111030daf6181ddf82d475b5b8a877e 100644
--- a/producer/api/cpp/unittests/test_request_handler_tcp.cpp
+++ b/producer/api/cpp/unittests/test_request_handler_tcp.cpp
@@ -195,7 +195,7 @@ void RequestHandlerTcpTests::ExpectFailAuthorize(bool only_once) {
     int i = 0;
     for (auto expected_sd : expected_sds) {
         EXPECT_CALL(mock_io,
-                    Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, expected_beamtime_id,
+                    Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, "",
                                                                ""),
                            sizeof(asapo::GenericRequestHeader), _))
             .WillOnce(
@@ -203,6 +203,13 @@ void RequestHandlerTcpTests::ExpectFailAuthorize(bool only_once) {
                     testing::SetArgPointee<3>(nullptr),
                     Return(sizeof(asapo::GenericRequestHeader))
                 ));
+        EXPECT_CALL(mock_io,
+                    Send_t(expected_sd, _,strlen(expected_beamtime_id), _))
+            .WillOnce(
+                DoAll(
+                    testing::SetArgPointee<3>(nullptr),
+                    Return(strlen(expected_beamtime_id))
+                ));
 
         EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _))
             .InSequence(seq_receive[i])
@@ -236,7 +243,7 @@ void RequestHandlerTcpTests::ExpectOKAuthorize(bool only_once) {
     int i = 0;
     for (auto expected_sd : expected_sds) {
         EXPECT_CALL(mock_io,
-                    Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, expected_beamtime_id,
+                    Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, "",
                                                                ""),
                            sizeof(asapo::GenericRequestHeader), _))
             .WillOnce(
@@ -244,6 +251,13 @@ void RequestHandlerTcpTests::ExpectOKAuthorize(bool only_once) {
                     testing::SetArgPointee<3>(nullptr),
                     Return(sizeof(asapo::GenericRequestHeader))
                 ));
+        EXPECT_CALL(mock_io,
+                    Send_t(expected_sd, _,strlen(expected_beamtime_id), _))
+            .WillOnce(
+                DoAll(
+                    testing::SetArgPointee<3>(nullptr),
+                    Return(strlen(expected_beamtime_id))
+                ));
 
         EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _))
             .InSequence(seq_receive[i])
diff --git a/receiver/src/request_handler/request_factory.cpp b/receiver/src/request_handler/request_factory.cpp
index fdacdd94a3c4eed52152fddc0489786f85b76818..de3f74cec40946b86836c391a28e85001bef8320 100644
--- a/receiver/src/request_handler/request_factory.cpp
+++ b/receiver/src/request_handler/request_factory.cpp
@@ -47,7 +47,9 @@ Error RequestFactory::AddReceiveDirectToFileHandler(std::unique_ptr<Request> &re
 
 Error RequestFactory::AddHandlersToRequest(std::unique_ptr<Request> &request,
                                            const GenericRequestHeader &request_header) const {
-    request->AddHandler(&request_handler_authorize_);
+    if (request_header.op_code != Opcode::kOpcodeAuthorize) {
+        request->AddHandler(&request_handler_authorize_);
+    }
 
     switch (request_header.op_code) {
         case Opcode::kOpcodeTransferData:
@@ -73,7 +75,8 @@ Error RequestFactory::AddHandlersToRequest(std::unique_ptr<Request> &request,
             break;
         }
         case Opcode::kOpcodeAuthorize: {
-            // do nothing
+            request->AddHandler(&request_handler_receive_metadata_);
+            request->AddHandler(&request_handler_authorize_);
             break;
         }
         case Opcode::kOpcodeStreamInfo: {
diff --git a/receiver/src/request_handler/request_handler_authorize.cpp b/receiver/src/request_handler/request_handler_authorize.cpp
index f13fc1ae28a41cedcd44ba348544e4c1e6c9d4fa..f3dbfa3650e09d1dc3a5e31575ca0ade68463cce 100644
--- a/receiver/src/request_handler/request_handler_authorize.cpp
+++ b/receiver/src/request_handler/request_handler_authorize.cpp
@@ -26,6 +26,14 @@ Error RequestHandlerAuthorize::ErrorFromAuthorizationServerResponse(const Error&
     }
 }
 
+Error CheckAccessType(const std::string& access_type) {
+    if (access_type!="write") {
+        return asapo::ReceiverErrorTemplates::kAuthorizationFailure.Generate("wrong access type: " + access_type);
+    }
+    return nullptr;
+}
+
+
 Error RequestHandlerAuthorize::Authorize(Request* request, const char* source_credentials) const {
     HttpCode code;
     Error err;
@@ -42,6 +50,7 @@ Error RequestHandlerAuthorize::Authorize(Request* request, const char* source_cr
     }
 
     std::string stype;
+    std::string access_type;
 
     JsonStringParser parser{response};
     (err = parser.GetString("beamtimeId", &beamtime_id_)) ||
@@ -49,15 +58,24 @@ Error RequestHandlerAuthorize::Authorize(Request* request, const char* source_cr
     (err = parser.GetString("core-path", &offline_path_)) ||
     (err = parser.GetString("beamline-path", &online_path_)) ||
     (err = parser.GetString("source-type", &stype)) ||
+    (err = parser.GetString("access-type", &access_type)) ||
     (err = GetSourceTypeFromString(stype, &source_type_)) ||
     (err = parser.GetString("beamline", &beamline_));
     if (err) {
         return ErrorFromAuthorizationServerResponse(err, code);
-    } else {
-        log__->Debug(std::string("authorized connection from ") + request->GetOriginUri() +"source type: "+stype+ " beamline: " +
-                     beamline_ + ", beamtime id: " + beamtime_id_ + ", data soucre: " + data_source_);
     }
 
+    err = CheckAccessType(access_type);
+    if (err) {
+        log__->Error("failure authorizing at " + GetReceiverConfig()->authorization_server + " request: " + request_string +
+            " - " +
+            err->Explain());
+        return err;
+    }
+
+    log__->Debug(std::string("authorized connection from ") + request->GetOriginUri() +"source type: "+stype+ " beamline: " +
+                     beamline_ + ", beamtime id: " + beamtime_id_ + ", data soucre: " + data_source_);
+
     last_updated_ = system_clock::now();
     cached_source_credentials_ = source_credentials;
 
@@ -73,7 +91,7 @@ Error RequestHandlerAuthorize::ProcessAuthorizationRequest(Request* request) con
         return auth_error;
     }
 
-    return Authorize(request, request->GetMessage());
+    return Authorize(request, request->GetMetaData().c_str());
 }
 
 Error RequestHandlerAuthorize::ProcessReAuthorization(Request* request) const {
diff --git a/receiver/unittests/request_handler/test_request_factory.cpp b/receiver/unittests/request_handler/test_request_factory.cpp
index 5f224d3d01135bacd0906518eccd10ba51c7aa72..a6c1d02b6c6479928f8b625d96fdcd1ba73a331b 100644
--- a/receiver/unittests/request_handler/test_request_factory.cpp
+++ b/receiver/unittests/request_handler/test_request_factory.cpp
@@ -121,7 +121,8 @@ TEST_F(FactoryTests, ReturnsDataRequestForAuthorizationCode) {
 
     ASSERT_THAT(err, Eq(nullptr));
     ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr));
-    ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerAuthorize*>(request->GetListHandlers()[0]), Ne(nullptr));
+    ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[0]), Ne(nullptr));
+    ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerAuthorize*>(request->GetListHandlers()[1]), Ne(nullptr));
 }
 
 TEST_F(FactoryTests, DoNotAddDiskAndDbWriterIfNotWantedInRequest) {
diff --git a/receiver/unittests/request_handler/test_request_handler_authorizer.cpp b/receiver/unittests/request_handler/test_request_handler_authorizer.cpp
index c1e5a97410fb279f029ee9a3447c67ba4abce3a2..e85038de4c1cf9dbb23e6e4d336179840b7bf959 100644
--- a/receiver/unittests/request_handler/test_request_handler_authorizer.cpp
+++ b/receiver/unittests/request_handler/test_request_handler_authorizer.cpp
@@ -74,6 +74,7 @@ class AuthorizerHandlerTests : public Test {
     std::string expected_source_credentials;
     asapo::SourceType expected_source_type = asapo::SourceType::kProcessed;
     std::string expected_source_type_str = "processed";
+    std::string expected_access_type_str = "write";
     void MockRequestData();
     void SetUp() override {
         GenericRequestHeader request_header;
@@ -115,7 +116,8 @@ class AuthorizerHandlerTests : public Test {
                              "\",\"beamline-path\":" + "\"" + expected_beamline_path +
                              "\",\"core-path\":" + "\"" + expected_core_path +
                              "\",\"source-type\":" + "\"" + expected_source_type_str +
-                             "\",\"beamline\":" + "\"" + expected_beamline + "\"}")
+                             "\",\"beamline\":" + "\"" + expected_beamline +
+                             "\",\"access-type\":" + "\"" + expected_access_type_str + "\"}")
                      ));
             if (code != HttpCode::OK) {
                 EXPECT_CALL(mock_logger, Error(AllOf(HasSubstr("failure authorizing"),
@@ -126,13 +128,16 @@ class AuthorizerHandlerTests : public Test {
                                                      HasSubstr(expected_data_source),
                                                      HasSubstr(expected_producer_uri),
                                                      HasSubstr(expected_authorization_server))));
-            } else {
+            } else if (expected_access_type_str=="write") {
                 EXPECT_CALL(mock_logger, Debug(AllOf(HasSubstr("authorized"),
                                                      HasSubstr(expected_beamtime_id),
                                                      HasSubstr(expected_beamline),
                                                      HasSubstr(expected_source_type_str),
                                                      HasSubstr(expected_data_source),
                                                      HasSubstr(expected_producer_uri))));
+            } else {
+                EXPECT_CALL(mock_logger, Error(AllOf(HasSubstr(expected_access_type_str),
+                                                     HasSubstr(expected_access_type_str))));
             }
         }
 
@@ -142,8 +147,8 @@ class AuthorizerHandlerTests : public Test {
         EXPECT_CALL(*mock_request, GetOpCode())
         .WillOnce(Return(asapo::kOpcodeAuthorize))
         ;
-        EXPECT_CALL(*mock_request, GetMessage())
-        .WillOnce(Return(expected_source_credentials.c_str()))
+        EXPECT_CALL(*mock_request, GetMetaData())
+        .WillOnce(ReturnRef(expected_source_credentials))
         ;
 
         MockAuthRequest(error, code);
@@ -206,6 +211,14 @@ TEST_F(AuthorizerHandlerTests, AuthorizeOk) {
     ASSERT_THAT(err, Eq(nullptr));
 }
 
+
+TEST_F(AuthorizerHandlerTests, AuthorizeFailsOnWrongAccessType) {
+    expected_access_type_str = "read";
+    auto err = MockFirstAuthorization(false);
+
+    ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure));
+}
+
 TEST_F(AuthorizerHandlerTests, ErrorOnSecondAuthorize) {
     MockFirstAuthorization(false);
     EXPECT_CALL(*mock_request, GetOpCode())
diff --git a/receiver/unittests/statistics/test_receiver_statistics.cpp b/receiver/unittests/statistics/test_receiver_statistics.cpp
index 1d0c864e85f4c233e52d77cb00bc194b8f0d4872..b64fc20b0834011bdaacb4ec6bd4712fe930e331 100644
--- a/receiver/unittests/statistics/test_receiver_statistics.cpp
+++ b/receiver/unittests/statistics/test_receiver_statistics.cpp
@@ -120,11 +120,11 @@ TEST_F(ReceiverStatisticTests, TimerForAll) {
 
     auto stat = ExtractStat();
 
-    ASSERT_THAT(stat.extra_entities[StatisticEntity::kDatabase].second, Ge(0));
+    ASSERT_THAT(stat.extra_entities[StatisticEntity::kDatabase].second, Gt(0));
 
-    ASSERT_THAT(stat.extra_entities[StatisticEntity::kNetwork].second, Ge(0));
+    ASSERT_THAT(stat.extra_entities[StatisticEntity::kNetwork].second, Gt(0));
 
-    ASSERT_THAT(stat.extra_entities[StatisticEntity::kDisk].second, Ge(0));
+    ASSERT_THAT(stat.extra_entities[StatisticEntity::kDisk].second, Gt(0));
 }
 
 }
diff --git a/tests/automatic/authorizer/check_authorize/CMakeLists.txt b/tests/automatic/authorizer/check_authorize/CMakeLists.txt
index ef88646421bc885f00e27bb0069094613c3cfc71..811a295b62482cca1741d9b4bd81575df69609a5 100644
--- a/tests/automatic/authorizer/check_authorize/CMakeLists.txt
+++ b/tests/automatic/authorizer/check_authorize/CMakeLists.txt
@@ -15,6 +15,7 @@ if (WIN32)
 endif()
 
 configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret_admin.key auth_secret_admin.key COPYONLY)
 
 configure_file(beamtime-metadata-11111111.json beamtime-metadata-11111111.json COPYONLY)
 
diff --git a/tests/automatic/authorizer/check_authorize/check_linux.sh b/tests/automatic/authorizer/check_authorize/check_linux.sh
index 0471f37aece486d24c9823772231f960dc787fb4..21d2561126a943f2002641d227dae9b62e350664 100644
--- a/tests/automatic/authorizer/check_authorize/check_linux.sh
+++ b/tests/automatic/authorizer/check_authorize/check_linux.sh
@@ -19,28 +19,40 @@ mkdir -p asap3/petra3/gpfs/p00/2019/data/11000015
 mkdir -p beamline/p07/current
 cp beamtime-metadata* beamline/p07/current/
 
+#tokens
+AdminToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNvcGpyaXB0MzNlb2ZjbWJuZyIsInN1YiI6ImFkbWluIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6ImNyZWF0ZSJ9fQ.uRjtGPaRpOlOfKroijHRgMDNaZHnXsVPf0JaJ1XMg7o
+curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":"read"}' 127.0.0.1:5007/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:5007/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:5007/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:5007/authorize --stderr -  | tee /dev/stderr  | grep p00
 curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep detector
 
-token=onm80KQF8s6d2p_laW0S5IYanUUsLcnB3QO-6QQ1M90= #token for c20180508-000-COM20181
-curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%onm80KQF8s6d2p_laW0S5IYanUUsLcnB3QO-6QQ1M90=","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep detector
-curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%auto%detector%onm80KQF8s6d2p_laW0S5IYanUUsLcnB3QO-6QQ1M90=","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep p00
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxZWpyaXB0MzUybHQxNjhyZyIsInN1YiI6ImJ0X2MyMDE4MDUwOC0wMDAtQ09NMjAxODEiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.MDuQa_f0yOcn35xIgiCfoVVT56oTQ5tSiuKu9VqO_tE #token for c20180508-000-COM20181
+
+curl -v --silent --data "{\"SourceCredentials\":\"processed%c20180508-000-COM20181%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep detector
+curl -v --silent --data "{\"SourceCredentials\":\"processed%c20180508-000-COM20181%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep p00
 curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%bla","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 401
 
-token=dccMd3NT89i32Whz7yD4VQhmEJy6Kxc35wsBbWJLXp0= #token for 11000015
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxYnZqaXB0MzR0cTNtMGM5ZyIsInN1YiI6ImJ0XzExMDAwMDE1IiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6InJlYWQifX0.oiweTX_mHIRHkX7_jfOJfHM8lncapROfdQlD7cR7_84 #token for 11000015
 #beamtine not online
-curl -v --silent --data '{"SourceCredentials":"raw%11000015%%detector%dccMd3NT89i32Whz7yD4VQhmEJy6Kxc35wsBbWJLXp0=","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 401
+curl -v --silent --data "{\"SourceCredentials\":\"raw%11000015%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 401
+
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxYzNqaXB0MzR0cjlyOWhiZyIsInN1YiI6ImJ0XzExMDAwMDE2IiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6InJlYWQifX0.2UxFNyI9rNwX9H0ErPNjJxZBy9WEv7CYq1N1d-93Jmg #token for 11000016
+curl -v --silent --data "{\"SourceCredentials\":\"raw%11000016%%detector%${token}\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 401
 
-token=Jaas_xTpkB0Zy5dFwjs4kCrY7yXMfbnW8Ca1aYhyKBs= #token for 11000016
-curl -v --silent --data '{"SourceCredentials":"raw%11000016%%detector%Jaas_xTpkB0Zy5dFwjs4kCrY7yXMfbnW8Ca1aYhyKBs=","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 401
 
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxcmFyaXB0MzVjcWpuMmUxZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.KQFj3hOJRpc7hPqwJyYmnQ31IrR1zSz4EifUuulmP5E # for beamlne p07
+curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 11111111
+curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:5007\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 11111111
+curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:5007\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep p07
+curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:5007\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep /asap3/petra3/gpfs/p07/2020/data/11111111
 
-token=-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4= # for bl_p07
-curl -v --silent --data '{"SourceCredentials":"processed%auto%p07%detector%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=","OriginHost":"bla"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 11111111
-curl -v --silent --data '{"SourceCredentials":"raw%auto%p07%detector%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=","OriginHost":"127.0.0.1:5007"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep 11111111
-curl -v --silent --data '{"SourceCredentials":"raw%auto%p07%detector%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=","OriginHost":"127.0.0.1:5007"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep p07
-curl -v --silent --data '{"SourceCredentials":"raw%auto%p07%detector%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=","OriginHost":"127.0.0.1:5007"}' 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep /asap3/petra3/gpfs/p07/2020/data/11111111
+#read access
+curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr  | grep read
 
+#write access
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTQ4MG1yaXB0Mzc2Z2xvNWo3MCIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJ3cml0ZSJ9fQ.8e4Xo1w-ICJzKjOwj2sGtpVfGppSGgPHv1yPLJwsdSA # for beamlne p07, write access
+curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr -  | tee /dev/stderr  | grep write
 
 rm -rf asap3 beamline
\ No newline at end of file
diff --git a/tests/automatic/authorizer/check_authorize/check_windows.bat b/tests/automatic/authorizer/check_authorize/check_windows.bat
index c90cce0d6993493cea730a1cd5226ef6cc021018..64a02ff130fb865098dd7395b50314f59c5c5b6a 100644
--- a/tests/automatic/authorizer/check_authorize/check_windows.bat
+++ b/tests/automatic/authorizer/check_authorize/check_windows.bat
@@ -15,7 +15,8 @@ C:\Curl\curl.exe -v  --silent --data "{\"SourceCredentials\":\"processed%%c20180
 
 C:\Curl\curl.exe -v  --silent --data "{\"SourceCredentials\":\"raw%%c20180508-000-COM20181%%%%detector%%wrong\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 401  || goto :error
 
-C:\Curl\curl.exe -v  --silent --data "{\"SourceCredentials\":\"raw%%auto%%p07%%detector%%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111  || goto :error
+set token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxcmFyaXB0MzVjcWpuMmUxZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.KQFj3hOJRpc7hPqwJyYmnQ31IrR1zSz4EifUuulmP5E"
+C:\Curl\curl.exe -v  --silent --data "{\"SourceCredentials\":\"raw%%auto%%p07%%detector%%%token%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111  || goto :error
 
 goto :clean
 
diff --git a/tests/automatic/authorizer/check_authorize/settings.json.in b/tests/automatic/authorizer/check_authorize/settings.json.in
index 51d5bfc3df247a96a4382d942bdbd372bb2dd497..13950ebea0ad1bc146c59042780fd02020c150a5 100644
--- a/tests/automatic/authorizer/check_authorize/settings.json.in
+++ b/tests/automatic/authorizer/check_authorize/settings.json.in
@@ -3,7 +3,8 @@
   "LogLevel":"debug",
   "RootBeamtimesFolder":"@ASAP3_FOLDER@",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "Ldap":
     {
         "Uri" : "ldap://localhost:389",
diff --git a/tests/automatic/broker/check_monitoring/CMakeLists.txt b/tests/automatic/broker/check_monitoring/CMakeLists.txt
index e5d07dee9d13103e2f4d7edfd5f8132b48407a50..05ef150fd611bf31a545ec5573b3acfc4c0db959 100644
--- a/tests/automatic/broker/check_monitoring/CMakeLists.txt
+++ b/tests/automatic/broker/check_monitoring/CMakeLists.txt
@@ -3,8 +3,8 @@ set(TARGET_NAME asapo-broker)
 ################################
 # Testing
 ################################
+prepare_asapo()
 configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json settings.json COPYONLY)
-configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
 
 add_script_test("${TARGET_NAME}-monitoring" "$<TARGET_PROPERTY:${TARGET_NAME},EXENAME> $<TARGET_PROPERTY:asapo,EXENAME>" nomem
         )
diff --git a/tests/automatic/broker/check_monitoring/check_linux.sh b/tests/automatic/broker/check_monitoring/check_linux.sh
index caf55e77f9b566a57e8b945639adf54b45c861a1..cc7b53abb8dda8104ac75f322dd858912215d3ad 100644
--- a/tests/automatic/broker/check_monitoring/check_linux.sh
+++ b/tests/automatic/broker/check_monitoring/check_linux.sh
@@ -11,12 +11,20 @@ Cleanup() {
 	echo cleanup
 	influx -execute "drop database ${database_name}"
 	kill -9 $brokerid
+  nomad stop nginx
+  nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
+  nomad stop authorizer
 }
 
 ! influx -execute "drop database ${database_name}"
 
 
-token=`$2 token -secret auth_secret.key data`
+nomad run nginx.nmd
+nomad run authorizer.nmd
+sleep 1
+
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5MzU3NjgsImp0aSI6ImMxNGNwbTNpcHQzZGRrbnFwYm9nIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.Jnhmj2i8zUbTzlmRCo6CUkqkD_FdyMxfNj_PztmnN-0
+
 
 $1 -config settings.json &
 
diff --git a/tests/automatic/broker/get_last/CMakeLists.txt b/tests/automatic/broker/get_last/CMakeLists.txt
index d9f88dc2d467b13ad24b542abfe7235d0c7cfd93..3b688f5db85a0a377f372e734cbd66264737768f 100644
--- a/tests/automatic/broker/get_last/CMakeLists.txt
+++ b/tests/automatic/broker/get_last/CMakeLists.txt
@@ -3,8 +3,8 @@ set(TARGET_NAME asapo-broker)
 ################################
 # Testing
 ################################
+prepare_asapo()
+
 configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json settings.json COPYONLY)
-configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
 
-add_script_test("${TARGET_NAME}-getlast" "$<TARGET_PROPERTY:${TARGET_NAME},EXENAME> $<TARGET_PROPERTY:asapo,EXENAME>" nomem
-        )
+add_script_test("${TARGET_NAME}-getlast" "$<TARGET_PROPERTY:${TARGET_NAME},EXENAME> $<TARGET_PROPERTY:asapo,EXENAME>" nomem)
diff --git a/tests/automatic/broker/get_last/check_linux.sh b/tests/automatic/broker/get_last/check_linux.sh
index a721a07b225b5a56241819c7dc80c22386438d20..643002fb7302b43c3a8bbd40581c0cd62f27f25e 100644
--- a/tests/automatic/broker/get_last/check_linux.sh
+++ b/tests/automatic/broker/get_last/check_linux.sh
@@ -11,12 +11,19 @@ Cleanup() {
 	echo cleanup
 	echo "db.dropDatabase()" | mongo ${database_name}
 	kill -9 $brokerid
+  nomad stop nginx
+  nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
+  nomad stop authorizer
 }
 
 echo "db.data_${stream}.insert({"_id":2})" | mongo ${database_name}
 echo "db.data_${stream}.insert({"_id":1})" | mongo ${database_name}
 
-token=`$2 token -secret auth_secret.key data`
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5MzU3NjgsImp0aSI6ImMxNGNwbTNpcHQzZGRrbnFwYm9nIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.Jnhmj2i8zUbTzlmRCo6CUkqkD_FdyMxfNj_PztmnN-0
+
+nomad run nginx.nmd
+nomad run authorizer.nmd
+sleep 1
 
 $1 -config settings.json &
 
diff --git a/tests/automatic/broker/get_last/check_windows.bat b/tests/automatic/broker/get_last/check_windows.bat
index bc2cfdada576cdb8c12ff416df8f59716dccc274..9830fcec3f5561cdb10eeedfd4801192b469292e 100644
--- a/tests/automatic/broker/get_last/check_windows.bat
+++ b/tests/automatic/broker/get_last/check_windows.bat
@@ -7,8 +7,12 @@ echo db.data_default.insert({"_id":2}) | %mongo_exe% %database_name%  || goto :e
 set full_name="%1"
 set short_name="%~nx1"
 
-"%2" token -secret auth_secret.key data > token
-set /P token=< token
+c:\opt\consul\nomad run authorizer.nmd
+c:\opt\consul\nomad run nginx.nmd
+ping 192.0.2.1 -n 1 -w 3000 > nul
+
+
+set token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5MzU3NjgsImp0aSI6ImMxNGNwbTNpcHQzZGRrbnFwYm9nIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.Jnhmj2i8zUbTzlmRCo6CUkqkD_FdyMxfNj_PztmnN-0
 
 start /B "" "%full_name%" -config settings.json
 ping 192.0.2.1 -n 1 -w 1000 > nul
@@ -44,5 +48,7 @@ exit /b 1
 :clean
 Taskkill /IM "%short_name%" /F
 echo db.dropDatabase() | %mongo_exe% %database_name%
-del /f token
-del /f groupid
\ No newline at end of file
+del /f groupid
+c:\opt\consul\nomad stop authorizer
+c:\opt\consul\nomad stop nginx
+c:\opt\consul\nomad run nginx_kill.nmd  && c:\opt\consul\nomad stop -yes -purge nginx_kill
diff --git a/tests/automatic/broker/get_meta/CMakeLists.txt b/tests/automatic/broker/get_meta/CMakeLists.txt
index 3888fa09d1101324253c44864d9fcdaf6907fe18..dc491f8bf71ff293f831de25273b189a82d2e253 100644
--- a/tests/automatic/broker/get_meta/CMakeLists.txt
+++ b/tests/automatic/broker/get_meta/CMakeLists.txt
@@ -3,8 +3,9 @@ set(TARGET_NAME asapo-broker)
 ################################
 # Testing
 ################################
+prepare_asapo()
+
 configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json settings.json COPYONLY)
-configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
 
 add_script_test("${TARGET_NAME}-getmeta" "$<TARGET_PROPERTY:${TARGET_NAME},EXENAME> $<TARGET_PROPERTY:asapo,EXENAME>" nomem
         )
diff --git a/tests/automatic/broker/get_meta/check_linux.sh b/tests/automatic/broker/get_meta/check_linux.sh
index 57b2e3335ff8e43ee8b071d4b68b1620fa1caa6e..a0a1c5dc0e7c0d9d3093a50e0acacbcaa851d528 100644
--- a/tests/automatic/broker/get_meta/check_linux.sh
+++ b/tests/automatic/broker/get_meta/check_linux.sh
@@ -10,11 +10,19 @@ Cleanup() {
 	echo cleanup
 	echo "db.dropDatabase()" | mongo ${database_name}
 	kill -9 $brokerid
+  nomad stop nginx
+  nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
+  nomad stop authorizer
 }
 
 echo 'db.meta.insert({"_id":0,"data":"test"})' | mongo ${database_name}
 
-token=`$2 token -secret auth_secret.key test`
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5MzU5MDEsImp0aSI6ImMxNGNxbmJpcHQzZGY2bDRvNHIwIiwic3ViIjoiYnRfdGVzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.D71Gv2AwSPIEkaeejWXs70sSoQzvKDonrTmtPk2J9AI
+
+nomad run nginx.nmd
+nomad run authorizer.nmd
+sleep 1
+
 
 $1 -config settings.json &
 
diff --git a/tests/automatic/broker/get_meta/check_windows.bat b/tests/automatic/broker/get_meta/check_windows.bat
index dc39360ad6fbd96ecd35bf7aa8d8e27766ea63e8..5372fc77de0cf6bcbdb6f46dfef9329981a1c3b6 100644
--- a/tests/automatic/broker/get_meta/check_windows.bat
+++ b/tests/automatic/broker/get_meta/check_windows.bat
@@ -6,8 +6,12 @@ echo db.meta.insert({"_id":0}) | %mongo_exe% %database_name%  || goto :error
 set full_name="%1"
 set short_name="%~nx1"
 
-"%2" token -secret auth_secret.key data > token
-set /P token=< token
+c:\opt\consul\nomad run authorizer.nmd
+c:\opt\consul\nomad run nginx.nmd
+ping 192.0.2.1 -n 1 -w 3000 > nul
+
+
+set token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5MzU3NjgsImp0aSI6ImMxNGNwbTNpcHQzZGRrbnFwYm9nIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.Jnhmj2i8zUbTzlmRCo6CUkqkD_FdyMxfNj_PztmnN-0
 
 start /B "" "%full_name%" -config settings.json
 
@@ -26,5 +30,7 @@ exit /b 1
 :clean
 Taskkill /IM "%short_name%" /F
 echo db.dropDatabase() | %mongo_exe% %database_name%
-del /f token
-del /f groupid
\ No newline at end of file
+del /f groupid
+c:\opt\consul\nomad stop authorizer
+c:\opt\consul\nomad stop nginx
+c:\opt\consul\nomad run nginx_kill.nmd  && c:\opt\consul\nomad stop -yes -purge nginx_kill
diff --git a/tests/automatic/broker/get_next/CMakeLists.txt b/tests/automatic/broker/get_next/CMakeLists.txt
index 7a87036704e2e71ad5318e6c5cb978277a495b7b..1eba288a03006af23d30193982fb3fda054548a1 100644
--- a/tests/automatic/broker/get_next/CMakeLists.txt
+++ b/tests/automatic/broker/get_next/CMakeLists.txt
@@ -3,8 +3,9 @@ set(TARGET_NAME asapo-broker)
 ################################
 # Testing
 ################################
+prepare_asapo()
+
 configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json settings.json COPYONLY)
-configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/auth_secret.key auth_secret.key COPYONLY)
 
 add_script_test("${TARGET_NAME}-getnext" "$<TARGET_PROPERTY:${TARGET_NAME},EXENAME> $<TARGET_PROPERTY:asapo,EXENAME>" nomem
         )
diff --git a/tests/automatic/broker/get_next/check_linux.sh b/tests/automatic/broker/get_next/check_linux.sh
index 277f78895f75804530199be5f17a3856bbbe9a63..195338dfc09b2e9771b81b2ce5b3febb4d322c56 100644
--- a/tests/automatic/broker/get_next/check_linux.sh
+++ b/tests/automatic/broker/get_next/check_linux.sh
@@ -11,12 +11,20 @@ Cleanup() {
 	echo cleanup
 	echo "db.dropDatabase()" | mongo ${database_name}
 	kill -9 $brokerid
+  nomad stop nginx
+  nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
+  nomad stop authorizer
 }
 
 echo "db.data_${stream}.insert({"_id":2})" | mongo ${database_name}
 echo "db.data_${stream}.insert({"_id":1})" | mongo ${database_name}
 
-token=`$2 token -secret auth_secret.key data`
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDIxMjcsImp0aSI6ImMxNGViYnJpcHQzZHQ4Y2JhczUwIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.U776By_privbW9WbQCSTmk9hLZVTXzTWNNap1XOIFlM
+
+nomad run nginx.nmd
+nomad run authorizer.nmd
+sleep 1
+
 
 $1 -config settings.json &
 
diff --git a/tests/automatic/broker/get_next/check_windows.bat b/tests/automatic/broker/get_next/check_windows.bat
index 0f3962bc4b44d9bc89267a8f2cce0728ccd79df7..fee3de987a77f41b2a3a2da96437ce91f314e83b 100644
--- a/tests/automatic/broker/get_next/check_windows.bat
+++ b/tests/automatic/broker/get_next/check_windows.bat
@@ -1,4 +1,4 @@
-SET database_name=data_detector
+SET database_name=data_source
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
 
 echo db.data_default.insert({"_id":1}) | %mongo_exe% %database_name%  || goto :error
@@ -7,8 +7,12 @@ echo db.data_default.insert({"_id":2}) | %mongo_exe% %database_name%  || goto :e
 set full_name="%1"
 set short_name="%~nx1"
 
-"%2" token -secret auth_secret.key data > token
-set /P token=< token
+set token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDIxMjcsImp0aSI6ImMxNGViYnJpcHQzZHQ4Y2JhczUwIiwic3ViIjoiYnRfZGF0YSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.U776By_privbW9WbQCSTmk9hLZVTXzTWNNap1XOIFlM
+
+c:\opt\consul\nomad run authorizer.nmd
+c:\opt\consul\nomad run nginx.nmd
+ping 192.0.2.1 -n 1 -w 3000 > nul
+
 
 start /B "" "%full_name%" -config settings.json
 
@@ -16,13 +20,13 @@ ping 192.0.2.1 -n 1 -w 1000 > nul
 
 C:\Curl\curl.exe -d '' --silent 127.0.0.1:5005/creategroup > groupid
 set /P groupid=< groupid
-C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/detector/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":1  || goto :error
-C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/detector/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":2  || goto :error
-C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/detector/default/%groupid%/next?token=%token% --stderr - | findstr  /c:\"id_max\":2  || goto :error
+C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/source/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":1  || goto :error
+C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/source/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":2  || goto :error
+C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/source/default/%groupid%/next?token=%token% --stderr - | findstr  /c:\"id_max\":2  || goto :error
 
 C:\Curl\curl.exe -d '' --silent 127.0.0.1:5005/creategroup > groupid
 set /P groupid=< groupid
-C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/detector/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":1  || goto :error
+C:\Curl\curl.exe -v  --silent 127.0.0.1:5005/database/data/source/default/%groupid%/next?token=%token% --stderr - | findstr /c:\"_id\":1  || goto :error
 
 goto :clean
 
@@ -34,4 +38,7 @@ exit /b 1
 Taskkill /IM "%short_name%" /F
 echo db.dropDatabase() | %mongo_exe% %database_name%
 del /f token
-del /f groupid
\ No newline at end of file
+del /f groupid
+c:\opt\consul\nomad stop authorizer
+c:\opt\consul\nomad stop nginx
+c:\opt\consul\nomad run nginx_kill.nmd  && c:\opt\consul\nomad stop -yes -purge nginx_kill
diff --git a/tests/automatic/bug_fixes/consumer_python_memleak/check_linux.sh b/tests/automatic/bug_fixes/consumer_python_memleak/check_linux.sh
index 21f6774fb85e118e2cf53a12447be4970b3c58f8..4f8e40847b8ab78aaa164f19b94481646be67daf 100644
--- a/tests/automatic/bug_fixes/consumer_python_memleak/check_linux.sh
+++ b/tests/automatic/bug_fixes/consumer_python_memleak/check_linux.sh
@@ -6,7 +6,8 @@ trap Cleanup EXIT
 endpoint=127.0.0.1:8400
 path=.
 beamtime_id=asapo_test
-token="IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk="
+#asapo_test read token
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 
 Cleanup() {
diff --git a/tests/automatic/bug_fixes/producer_send_after_restart/check_windows.bat b/tests/automatic/bug_fixes/producer_send_after_restart/check_windows.bat
index c71a4d9fae13c1927ddfd5c73c9579208ebf1e38..ee6f034540209846a58a78c94ed2620efbe60ea6 100644
--- a/tests/automatic/bug_fixes/producer_send_after_restart/check_windows.bat
+++ b/tests/automatic/bug_fixes/producer_send_after_restart/check_windows.bat
@@ -8,16 +8,15 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
 REM producer
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in\processed
diff --git a/tests/automatic/consumer/consumer_api/check_linux.sh b/tests/automatic/consumer/consumer_api/check_linux.sh
index 5d4d146969cb33f931535e976356e66dd24a718c..f674a67ed37f4b94c8428100c51d165cd30254fb 100644
--- a/tests/automatic/consumer/consumer_api/check_linux.sh
+++ b/tests/automatic/consumer/consumer_api/check_linux.sh
@@ -3,7 +3,7 @@
 beamtime_id=test_run
 data_source=detector
 database_name=${beamtime_id}_${data_source}
-token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 set -e
 
@@ -14,6 +14,7 @@ Cleanup() {
     nomad stop nginx
     nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
     nomad stop discovery
+    nomad stop authorizer
     nomad stop broker
     echo "db.dropDatabase()" | mongo ${database_name}
 	rm -f 1_1 1
@@ -22,6 +23,7 @@ Cleanup() {
 
 nomad run nginx.nmd
 nomad run discovery.nmd
+nomad run authorizer.nmd
 nomad run broker.nmd
 
 sleep 1
diff --git a/tests/automatic/consumer/consumer_api/check_windows.bat b/tests/automatic/consumer/consumer_api/check_windows.bat
index 908980541836aede7a5e8685efdd137c87896052..4764a3852817ba8eb4f4e14030b62c6be40a6ec3 100644
--- a/tests/automatic/consumer/consumer_api/check_windows.bat
+++ b/tests/automatic/consumer/consumer_api/check_windows.bat
@@ -4,7 +4,7 @@ SET data_source=detector
 
 SET database_name=%beamtime_id%_%data_source%
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
-set token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+set token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 call start_services.bat
 
diff --git a/tests/automatic/consumer/consumer_api_python/authorizer_settings.json.tpl.in b/tests/automatic/consumer/consumer_api_python/authorizer_settings.json.tpl.in
index d4916f87e39ca954a28ffc6e72199acd0d046c3f..611bdefecbc64cd2c976e69593975c81eaf57b13 100644
--- a/tests/automatic/consumer/consumer_api_python/authorizer_settings.json.tpl.in
+++ b/tests/automatic/consumer/consumer_api_python/authorizer_settings.json.tpl.in
@@ -3,7 +3,8 @@
   "LogLevel":"debug",
   "RootBeamtimesFolder":"@ASAP3_FOLDER@",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
     {
diff --git a/tests/automatic/consumer/consumer_api_python/check_linux.sh b/tests/automatic/consumer/consumer_api_python/check_linux.sh
index aed808f5de44e225a8bb83dfc9e926098d9ec6c8..47396174ee2d5d7d7c5a61d60a53786fdb0dec65 100644
--- a/tests/automatic/consumer/consumer_api_python/check_linux.sh
+++ b/tests/automatic/consumer/consumer_api_python/check_linux.sh
@@ -4,7 +4,7 @@ beamtime_id=test_run
 source_path=`pwd`/asap3/petra3/gpfs/p01/2019/data/$beamtime_id
 data_source=detector
 database_name=${beamtime_id}_${data_source}
-token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 set -e
 
 
diff --git a/tests/automatic/consumer/consumer_api_python/check_windows.bat b/tests/automatic/consumer/consumer_api_python/check_windows.bat
index a6e530432635fb23c88e4dad1b179f3f8283ddde..055a5efafc2ef849e7313f30436993d481ec8ae0 100644
--- a/tests/automatic/consumer/consumer_api_python/check_windows.bat
+++ b/tests/automatic/consumer/consumer_api_python/check_windows.bat
@@ -8,7 +8,7 @@ SET data_source=detector
 SET database_name=%beamtime_id%_%data_source%
 
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
-set token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+set token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 call start_services.bat
 
diff --git a/tests/automatic/consumer/next_multithread_broker/check_linux.sh b/tests/automatic/consumer/next_multithread_broker/check_linux.sh
index b172ad0ac649f3ec6646f1c71b3ce881fd55d61b..7da3c8b69223aa8d239bc56fb72f6a63488ab0e6 100644
--- a/tests/automatic/consumer/next_multithread_broker/check_linux.sh
+++ b/tests/automatic/consumer/next_multithread_broker/check_linux.sh
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 
 database_name=test_run_detector
-token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 set -e
 
@@ -12,6 +12,7 @@ Cleanup() {
     nomad stop nginx
     nomad run nginx_kill.nmd  && nomad stop -yes -purge nginx_kill
     nomad stop discovery
+    nomad stop authorizer
     nomad stop broker
 	echo "db.dropDatabase()" | mongo ${database_name}
 }
@@ -19,6 +20,7 @@ Cleanup() {
 
 nomad run nginx.nmd
 nomad run discovery.nmd
+nomad run authorizer.nmd
 nomad run broker.nmd
 
 sleep 1
diff --git a/tests/automatic/consumer/next_multithread_broker/check_windows.bat b/tests/automatic/consumer/next_multithread_broker/check_windows.bat
index 4a13c733a4e3764b4aa452e7e7af806fc6eb5f22..607adcff43d61835865d1840a4161ee9de3f47c1 100644
--- a/tests/automatic/consumer/next_multithread_broker/check_windows.bat
+++ b/tests/automatic/consumer/next_multithread_broker/check_windows.bat
@@ -1,6 +1,6 @@
 SET database_name=test_run_detector
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
-set token_test_run=K38Mqc90iRv8fC7prcFHd994mF_wfUiJnWBfIjIzieo=
+set token_test_run=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI0MjQsImp0aSI6ImMxNGVkbTNpcHQzZHQ4Y2JhczVnIiwic3ViIjoiYnRfdGVzdF9ydW4iLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.SBzrEy-d3ayhVZMSskYUMLM2LVHw3yiM32mIOcITh0g
 
 call start_services.bat
 
diff --git a/tests/automatic/curl_http_client/curl_http_client_command/authorizer_settings.json.tpl.in b/tests/automatic/curl_http_client/curl_http_client_command/authorizer_settings.json.tpl.in
index d4916f87e39ca954a28ffc6e72199acd0d046c3f..611bdefecbc64cd2c976e69593975c81eaf57b13 100644
--- a/tests/automatic/curl_http_client/curl_http_client_command/authorizer_settings.json.tpl.in
+++ b/tests/automatic/curl_http_client/curl_http_client_command/authorizer_settings.json.tpl.in
@@ -3,7 +3,8 @@
   "LogLevel":"debug",
   "RootBeamtimesFolder":"@ASAP3_FOLDER@",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
     {
diff --git a/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp b/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp
index 33e1b6a6665255ebc048374b96c67505155b77ff..114137050e729f12beb8e9a453e7e4feada69403 100644
--- a/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp
+++ b/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp
@@ -28,7 +28,7 @@ Args GetArgs(int argc, char* argv[]) {
 int main(int argc, char* argv[]) {
 
     auto args = GetArgs(argc, argv);
-    auto token = "bnCXpOdBV90wU1zybEw1duQNSORuwaKz6oDHqmL35p0="; //token for aaa
+    auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NDI2MDMsImp0aSI6ImMxNGVmMnJpcHQzZHQ4Y2JhczYwIiwic3ViIjoiYnRfYWFhIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6InJlYWQifX0.xvU-EaemmBhcPzmCvjPVUkCxkTjglo-072aJZjDhGBM"; //token for aaa
     std::string authorize_request = "{\"Folder\":\"" + args.folder + "\",\"BeamtimeId\":\"aaa\",\"Token\":\"" + token +
                                     "\"}";
     asapo::Error err;
@@ -46,11 +46,11 @@ int main(int argc, char* argv[]) {
     std::string input_data;
     auto folder_token = consumer_impl->httpclient__->Post(args.uri_authorizer + "/folder", "", authorize_request, &code,
                         &err);
-    M_AssertTrue(err == nullptr);
-    M_AssertTrue(code == asapo::HttpCode::OK);
     if (err) {
         std::cout << err->Explain();
     }
+    M_AssertTrue(err == nullptr);
+    M_AssertTrue(code == asapo::HttpCode::OK);
 
     consumer_impl->httpclient__->Post(args.uri_authorizer + "/folder", "", "", &code, &err);
     M_AssertTrue(code == asapo::HttpCode::BadRequest);
diff --git a/tests/automatic/file_transfer_service/rest_api/authorizer_settings.json.tpl.in b/tests/automatic/file_transfer_service/rest_api/authorizer_settings.json.tpl.in
index d4916f87e39ca954a28ffc6e72199acd0d046c3f..611bdefecbc64cd2c976e69593975c81eaf57b13 100644
--- a/tests/automatic/file_transfer_service/rest_api/authorizer_settings.json.tpl.in
+++ b/tests/automatic/file_transfer_service/rest_api/authorizer_settings.json.tpl.in
@@ -3,7 +3,8 @@
   "LogLevel":"debug",
   "RootBeamtimesFolder":"@ASAP3_FOLDER@",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
     {
diff --git a/tests/automatic/file_transfer_service/rest_api/check_linux.sh b/tests/automatic/file_transfer_service/rest_api/check_linux.sh
index 04b478d498eedff2ca34c824bfed0c5473974289..4b1a7e4ffab3fa21749da112baf8016db091e542 100644
--- a/tests/automatic/file_transfer_service/rest_api/check_linux.sh
+++ b/tests/automatic/file_transfer_service/rest_api/check_linux.sh
@@ -21,7 +21,9 @@ sleep 1
 
 mkdir -p $file_transfer_folder
 
-token=bnCXpOdBV90wU1zybEw1duQNSORuwaKz6oDHqmL35p0= #token for aaa
+ #token for aaa
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhdTFiaXB0M2FzbzNoYzJvZyIsInN1YiI6ImJ0X2FhYSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.rvtEPZhvqwG91sod6-iBPCMUXWtMQtmFsqpXNv5HvFc
+
 folder_token=`curl --silent --data "{\"Folder\":\"$file_transfer_folder\",\"BeamtimeId\":\"aaa\",\"Token\":\"$token\"}" 127.0.0.1:5007/folder`
 echo $folder_token
 
diff --git a/tests/automatic/file_transfer_service/rest_api/check_windows.bat b/tests/automatic/file_transfer_service/rest_api/check_windows.bat
index 9814125d2df3f0805ebb51a6a14fe992bb0100c4..70d3d4c8d8b2929b04634e9036d2acee282b6226 100644
--- a/tests/automatic/file_transfer_service/rest_api/check_windows.bat
+++ b/tests/automatic/file_transfer_service/rest_api/check_windows.bat
@@ -9,7 +9,7 @@ c:\opt\consul\nomad run file_transfer.nmd
 
 ping 192.0.2.1 -n 1 -w 1000 > nul
 
-set token=bnCXpOdBV90wU1zybEw1duQNSORuwaKz6oDHqmL35p0=
+set token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhdTFiaXB0M2FzbzNoYzJvZyIsInN1YiI6ImJ0X2FhYSIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.rvtEPZhvqwG91sod6-iBPCMUXWtMQtmFsqpXNv5HvFc
 
 mkdir %file_transfer_folder%
 
diff --git a/tests/automatic/full_chain/send_recv_streams/check_linux.sh b/tests/automatic/full_chain/send_recv_streams/check_linux.sh
index f7f1f0241bd2b973a45ef4c8141053c3209dbccf..949ac36eddb18df4e421c730b179098621428cbb 100644
--- a/tests/automatic/full_chain/send_recv_streams/check_linux.sh
+++ b/tests/automatic/full_chain/send_recv_streams/check_linux.sh
@@ -5,7 +5,9 @@ beamtime_id=asapo_test
 stream_in=detector
 
 indatabase_name=${beamtime_id}_${stream_in}
-token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+
+#asapo_test read token
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 beamline=test
 
diff --git a/tests/automatic/full_chain/send_recv_streams/check_windows.bat b/tests/automatic/full_chain/send_recv_streams/check_windows.bat
index d89ca68c8e229b56fd09562bfa1712b2463490f6..c531b53797faca6e085617f5191af5e2a4b5334c 100644
--- a/tests/automatic/full_chain/send_recv_streams/check_windows.bat
+++ b/tests/automatic/full_chain/send_recv_streams/check_windows.bat
@@ -4,7 +4,7 @@ SET stream_in=detector
 
 SET indatabase_name=%beamtime_id%_%stream_in%
 
-SET token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+SET token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 SET beamline=test
 
diff --git a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp
index 5f025e5f434998f801316a0be33e0426d7937334..9e18200837e755a3c9e2fbeca72d7064b1ab4cc3 100644
--- a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp
+++ b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp
@@ -75,7 +75,7 @@ ProducerPtr CreateProducer(const Args& args) {
 int main(int argc, char* argv[]) {
     asapo::ExitAfterPrintVersionIfNeeded("GetNext consumer Example", argc, argv);
     Args args;
-    if (argc != 5) {
+    if (argc != 4) {
         std::cout << "Usage: " + std::string{argv[0]}
                   + " <server> <network_type> <beamtime_id> <token>"
                   <<
diff --git a/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh b/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh
index 024acde6816e99ac39d9bcee2dabae58a9fbfe7b..d79f8c1b76719324b867a1bc9a1350a060d50833 100644
--- a/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh
+++ b/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh
@@ -5,7 +5,7 @@ beamtime_id=asapo_test
 stream_in=detector
 
 indatabase_name=${beamtime_id}_${stream_in}
-token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 
 beamline=test
 
diff --git a/tests/automatic/full_chain/send_recv_streams_python/check_windows.bat b/tests/automatic/full_chain/send_recv_streams_python/check_windows.bat
index 475943c379ac9a534bfd8afb91e9616585f9b055..333ae035116f2b05cbdb8a2f5b33f3ae8ab1a735 100644
--- a/tests/automatic/full_chain/send_recv_streams_python/check_windows.bat
+++ b/tests/automatic/full_chain/send_recv_streams_python/check_windows.bat
@@ -4,8 +4,7 @@ SET stream_in=detector
 
 SET indatabase_name=%beamtime_id%_%stream_in%
 
-SET token=IEfwsWa0GXky2S3MkxJSUHJT1sI8DD5teRdjBUXVRxk=
-
+SET token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhcDQzaXB0M2E0bmNpMDkwMCIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.X5Up3PBd81i4X7wUBXGkIrLEVSL-WO9kijDtzOqasgg
 SET beamline=test
 
 SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
diff --git a/tests/automatic/full_chain/simple_chain/check_linux.sh b/tests/automatic/full_chain/simple_chain/check_linux.sh
index fcc4a10f02dace183ace3188fd824821bed088e6..259b9292284c54ee979311c6ee925bc799dd4fdf 100755
--- a/tests/automatic/full_chain/simple_chain/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain/check_linux.sh
@@ -9,7 +9,6 @@ consumer_bin=$2
 asapo_tool_bin=$3
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -49,6 +48,9 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin localhost:8400 ${beamtime_id} 100 1000 4 0 100
diff --git a/tests/automatic/full_chain/simple_chain/check_windows.bat b/tests/automatic/full_chain/simple_chain/check_windows.bat
index 8ef712f1406b3e2d033ff796f04c55bf8095878b..135a342b3042493651a40ccb4f0a61f3fe2efd10 100644
--- a/tests/automatic/full_chain/simple_chain/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain/check_windows.bat
@@ -5,16 +5,15 @@ SET receiver_root_folder=c:\tmp\asapo\receiver\files
 
 SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
 REM producer
 mkdir %receiver_folder%
 start /B "" "%1" %proxy_address% %beamtime_id% 100 1000 4 0 100
diff --git a/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh b/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh
index 6972a6ef1174e7224eeed0c020aac6f6308919d0..2250eaaa5b659bd497b61d4cc31d172f6b735873 100644
--- a/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -46,6 +45,8 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin localhost:8400 ${beamtime_id} 100 100 4 0 100 5 &
diff --git a/tests/automatic/full_chain/simple_chain_dataset/check_windows.bat b/tests/automatic/full_chain/simple_chain_dataset/check_windows.bat
index 030c045ebd7ec2db441dade5d4ee3943453f1c36..f3c612e3fc9cd38bec62bbde6c21149bd44c7caf 100644
--- a/tests/automatic/full_chain/simple_chain_dataset/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_dataset/check_windows.bat
@@ -4,16 +4,15 @@ SET beamline=test
 SET receiver_root_folder=c:\tmp\asapo\receiver\files
 SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
 REM producer
 mkdir %receiver_folder%
 start /B "" "%1" %proxy_address% %beamtime_id% 100 100 4 0 100 5
diff --git a/tests/automatic/full_chain/simple_chain_filegen/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen/check_linux.sh
index 6720558682eecbc8ee9d4a81d3b8f522fee875bc..469211b3e1afede8b45ad4cec0543657210e47bc 100644
--- a/tests/automatic/full_chain/simple_chain_filegen/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_filegen/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -47,6 +46,8 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin test.json &
diff --git a/tests/automatic/full_chain/simple_chain_filegen/check_windows.bat b/tests/automatic/full_chain/simple_chain_filegen/check_windows.bat
index 1eeb2fe43079f45af4c2f645ee6da82f54805040..0687ae3aed8a9b186c5328c8444fb20abe464e25 100644
--- a/tests/automatic/full_chain/simple_chain_filegen/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_filegen/check_windows.bat
@@ -8,16 +8,16 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in\processed
diff --git a/tests/automatic/full_chain/simple_chain_filegen_batches/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_batches/check_linux.sh
index ef67e1cdd2e9eb132443449e291d91cb27121ea4..2a12c2a84164ae90a0efa775e20ac544d427d665 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_batches/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_filegen_batches/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -50,6 +49,9 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 mkdir  /tmp/asapo/test_in/processed/test1
 mkdir  /tmp/asapo/test_in/processed/test2
 
diff --git a/tests/automatic/full_chain/simple_chain_filegen_batches/check_windows.bat b/tests/automatic/full_chain/simple_chain_filegen_batches/check_windows.bat
index a8842020e2c58d1a4e5e578d17606fd162090f02..09406417657667e09877d10d605a81ddfb11a0a6 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_batches/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_filegen_batches/check_windows.bat
@@ -8,16 +8,16 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in\processed
diff --git a/tests/automatic/full_chain/simple_chain_filegen_multisource/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_multisource/check_linux.sh
index 5283a0d682e03bfacdd63bf2439b5c74e5ffe0a1..e7579449e6f28984275aa8c23190c7ca741dd0e9 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_multisource/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_filegen_multisource/check_linux.sh
@@ -9,7 +9,6 @@ consumer_bin=$2
 asapo_tool_bin=$3
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -48,6 +47,7 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
 
 mkdir -p /tmp/asapo/test_in1/processed
 mkdir -p /tmp/asapo/test_in2/processed
diff --git a/tests/automatic/full_chain/simple_chain_filegen_multisource/check_windows.bat b/tests/automatic/full_chain/simple_chain_filegen_multisource/check_windows.bat
index 8ae26ac1400799601c979724ba5697128bb9f5f0..6e346be0bf570842df1d13a1bc16eea2ebb34a3d 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_multisource/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_filegen_multisource/check_windows.bat
@@ -8,16 +8,16 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
+
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in1\processed
 mkdir  c:\tmp\asapo\test_in2\processed
diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh
index b57cbbbad09a957ee9cab06d77a88f5fbdd7101c..cc1ffe2ca2ed3c4694901fc96aae377817c0dff5 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$3 token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -50,6 +49,8 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$3 token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin test.json &
diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_windows.bat b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_windows.bat
index 32754618f82a36e2316b561bb090f15daf8825c8..f9356e4a67e49a5d86dbaebd4279cfc63d8da20c 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_windows.bat
@@ -8,16 +8,16 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in\processed
diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh
index 6a571d4d27ce9b83586664d0b3ec60a80a4596b3..b59287d9a9ba501ef6f6758918726b1da74baf8c 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -50,6 +49,9 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin test.json &
diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_windows.bat b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_windows.bat
index e68b0ca6332b31a1d75a94e7cba303e94ae52b7a..c0b68bef17b4d5f103195e7d2c5ac2d394826a08 100644
--- a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_windows.bat
@@ -8,16 +8,16 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 
 set producer_short_name="%~nx1"
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 mkdir  c:\tmp\asapo\test_in\processed
diff --git a/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh b/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh
index d766e7ae9933ba3d88167dd64f3b05dbb5a410ce..b5fb650d915f9296d96d7442b3698698d5193af9 100644
--- a/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh
@@ -9,7 +9,6 @@ consumer_bin=$2
 asapo_tool_bin=$3
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -45,6 +44,9 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin localhost:8400 ${beamtime_id} 100 0 1 0 1000
diff --git a/tests/automatic/full_chain/simple_chain_metadata/check_windows.bat b/tests/automatic/full_chain/simple_chain_metadata/check_windows.bat
index 9dbba7db3e8c1d8487c9d0ccc19eb20d0e9226ea..38bc1fa6b3f4eb37ca3fec874a7e9397b6756372 100644
--- a/tests/automatic/full_chain/simple_chain_metadata/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_metadata/check_windows.bat
@@ -4,15 +4,15 @@ SET beamline=test
 SET receiver_root_folder=c:\tmp\asapo\receiver\files
 SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
 
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
 REM producer
 mkdir %receiver_folder%
 "%1" %proxy_address% %beamtime_id% 100 0 1 0 1000
diff --git a/tests/automatic/full_chain/simple_chain_raw/check_linux.sh b/tests/automatic/full_chain/simple_chain_raw/check_linux.sh
index f56ee8ca5627333538906b17b4fcdac9de30dc97..3c1d99888df58ab46e2d323c32d50f94648ef7fb 100644
--- a/tests/automatic/full_chain/simple_chain_raw/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_raw/check_linux.sh
@@ -5,7 +5,6 @@ set -e
 trap Cleanup EXIT
 
 beamtime_id=11111111
-token=`$3 token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -40,6 +39,8 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$3 token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 #producer
 $1 localhost:8400 ${beamtime_id} 100 10 4 100 100
 
diff --git a/tests/automatic/full_chain/simple_chain_raw/check_windows.bat b/tests/automatic/full_chain/simple_chain_raw/check_windows.bat
index 8f9eea4aad498cba4d88be434eb9ff3fcb37ae6c..cabbe08cae7dba38d89d1bbc2dd4fcc3f58147f4 100644
--- a/tests/automatic/full_chain/simple_chain_raw/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_raw/check_windows.bat
@@ -6,14 +6,15 @@ mkdir beamline\p07\current
 copy beamtime-metadata* beamline\p07\current\ /y
 copy beamtime-metadata* asap3\petra3\gpfs\p07\2019\data\11111111\ /y
 
-
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 start /B "" "%1" %proxy_address% %beamtime_id% 100 10 4 100 100
diff --git a/tests/automatic/full_chain/simple_chain_raw/settings.json.tpl.in b/tests/automatic/full_chain/simple_chain_raw/settings.json.tpl.in
index 4aecbe840466b510e46c567c4871bd892b110bcc..130d17e47a5489c0b6beb0fcd93edb4eab1b91ee 100644
--- a/tests/automatic/full_chain/simple_chain_raw/settings.json.tpl.in
+++ b/tests/automatic/full_chain/simple_chain_raw/settings.json.tpl.in
@@ -3,7 +3,8 @@
   "LogLevel":"debug",
   "RootBeamtimesFolder":"@ASAP3_FOLDER@",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "Ldap":
     {
         "Uri" : "ldap://localhost:389",
diff --git a/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh b/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh
index 3023c28f4c8a518836df54349c492d8c78ae6372..bca082f65443818ec8728adef6ade493f2946fef 100644
--- a/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh
+++ b/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh
@@ -8,7 +8,6 @@ producer_bin=$1
 asapo_tool_bin=$2
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -44,6 +43,9 @@ nomad run broker.nmd
 
 sleep 2
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 echo "Start producer"
 mkdir -p ${receiver_folder}
 $producer_bin localhost:8400 ${beamtime_id} 100 100 1 0 100
diff --git a/tests/automatic/full_chain/simple_chain_usermeta_python/check_windows.bat b/tests/automatic/full_chain/simple_chain_usermeta_python/check_windows.bat
index e68687fa6050d59c41fd987b0ad8ed026abb6445..14a0d6e3952da2046d7d02cd10f442d22f495bd9 100644
--- a/tests/automatic/full_chain/simple_chain_usermeta_python/check_windows.bat
+++ b/tests/automatic/full_chain/simple_chain_usermeta_python/check_windows.bat
@@ -4,16 +4,17 @@ SET beamline=test
 SET receiver_root_folder=c:\tmp\asapo\receiver\files
 SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
 
-
-"%2" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id%_detector.insert({dummy:1}) | %mongo_exe% %beamtime_id%_detector
 
 call start_services.bat
 
+"%2" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+
+set /P token=< token
+
+
 REM producer
 mkdir %receiver_folder%
 "%1" %proxy_address% %beamtime_id% 100 100 4 0 100
diff --git a/tests/automatic/full_chain/two_beamlines/check_linux.sh b/tests/automatic/full_chain/two_beamlines/check_linux.sh
index f518a57a459409d7bee58caf630ff87b4150601a..302b8380567d4bf62924b405a960d2542e83b9c8 100644
--- a/tests/automatic/full_chain/two_beamlines/check_linux.sh
+++ b/tests/automatic/full_chain/two_beamlines/check_linux.sh
@@ -12,10 +12,8 @@ network_type=$4
 data_source=detector
 
 beamtime_id1=asapo_test1
-token1=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id1`
 
 beamtime_id2=asapo_test2
-token2=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id2`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -56,6 +54,9 @@ nomad run broker.nmd
 
 sleep 3
 
+token1=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id1`
+token2=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id2`
+
 echo "Start producers"
 mkdir -p ${receiver_folder1}
 mkdir -p ${receiver_folder2}
diff --git a/tests/automatic/full_chain/two_beamlines/check_windows.bat b/tests/automatic/full_chain/two_beamlines/check_windows.bat
index 1f09a912ea9b8f0e886d9ba58a1edf9c241bc162..9504f9d3a6bdee23c73c0e98adf220685c1111d3 100644
--- a/tests/automatic/full_chain/two_beamlines/check_windows.bat
+++ b/tests/automatic/full_chain/two_beamlines/check_windows.bat
@@ -13,11 +13,6 @@ SET year=2019
 SET receiver_folder1="%receiver_root_folder%\%facility%\gpfs\%beamline1%\%year%\data\%beamtime_id1%"
 SET receiver_folder2="%receiver_root_folder%\%facility%\gpfs\%beamline2%\%year%\data\%beamtime_id2%"
 
-"%3" token -secret auth_secret.key %beamtime_id1% > token
-set /P token1=< token
-"%3" token -secret auth_secret.key %beamtime_id2% > token
-set /P token2=< token
-
 set proxy_address="127.0.0.1:8400"
 
 echo db.%beamtime_id1%_%data_source%.insert({dummy:1}) | %mongo_exe% %beamtime_id1%_%data_source%
@@ -25,6 +20,13 @@ echo db.%beamtime_id2%_%data_source%.insert({dummy:1}) | %mongo_exe% %beamtime_i
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id1% > token
+set /P token1=< token
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id2% > token
+set /P token2=< token
+
+
+
 REM producer
 mkdir %receiver_folder1%
 mkdir %receiver_folder2%
diff --git a/tests/automatic/full_chain/two_streams/check_linux.sh b/tests/automatic/full_chain/two_streams/check_linux.sh
index fbbe34ab9801818131ae7443a2a6203092b88579..cdf4e592109b12da9a248ec3d93a2afe4b99d06e 100644
--- a/tests/automatic/full_chain/two_streams/check_linux.sh
+++ b/tests/automatic/full_chain/two_streams/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 stream1=s1
 stream2=s2
@@ -49,6 +48,8 @@ nomad run broker.nmd
 
 sleep 3
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 echo "Start producers"
 mkdir -p ${receiver_folder}
 $producer_bin localhost:8400 ${beamtime_id}%${stream1} 100 1000 4 0 100 &
diff --git a/tests/automatic/full_chain/two_streams/check_windows.bat b/tests/automatic/full_chain/two_streams/check_windows.bat
index c2ba213cb82ae06693ea682576a93e35a714f2bc..67812b3ce876ae520f89c5a6c603e84c22ef598b 100644
--- a/tests/automatic/full_chain/two_streams/check_windows.bat
+++ b/tests/automatic/full_chain/two_streams/check_windows.bat
@@ -7,8 +7,6 @@ SET stream2=s2
 SET receiver_root_folder=c:\tmp\asapo\receiver\files
 SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
 
-"%3" token -secret auth_secret.key %beamtime_id% > token
-set /P token=< token
 
 set proxy_address="127.0.0.1:8400"
 
@@ -17,6 +15,9 @@ echo db.%beamtime_id%_%stream2%.insert({dummy:1}) | %mongo_exe% %beamtime_id%_%s
 
 call start_services.bat
 
+"%3" token -endpoint http://127.0.0.1:8400/asapo-authorizer -secret admin_token.key -type read %beamtime_id% > token
+set /P token=< token
+
 REM producer
 mkdir %receiver_folder%
 start /B "" "%1" %proxy_address% %beamtime_id%%%%stream1% 100 1000 4 0 100
diff --git a/tests/automatic/high_avail/broker_mongo_restart/check_linux.sh b/tests/automatic/high_avail/broker_mongo_restart/check_linux.sh
index 440d88d8ad6e6f2e018905e0bf7264c5afbd301c..c8fe078ca268437a69e4354e3f9f4c88f6a28650 100755
--- a/tests/automatic/high_avail/broker_mongo_restart/check_linux.sh
+++ b/tests/automatic/high_avail/broker_mongo_restart/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$4
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -81,6 +80,9 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
+
 echo "db.${beamtime_id}_detector.insert({dummy:1})" | mongo --port 27016 ${beamtime_id}_detector
 
 
diff --git a/tests/automatic/high_avail/services_restart/check_linux.sh b/tests/automatic/high_avail/services_restart/check_linux.sh
index 8020cb72ce5b0f32c0da551b0064fad4b219aada..d01713f908460e8f9ae2dd6c71153a717fa3c3cd 100644
--- a/tests/automatic/high_avail/services_restart/check_linux.sh
+++ b/tests/automatic/high_avail/services_restart/check_linux.sh
@@ -10,7 +10,6 @@ asapo_tool_bin=$3
 network_type=$7
 
 beamtime_id=asapo_test
-token=`$asapo_tool_bin token -secret auth_secret.key $beamtime_id`
 
 monitor_database_name=db_test
 proxy_address=127.0.0.1:8400
@@ -45,6 +44,8 @@ nomad run broker.nmd
 
 sleep 1
 
+token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -type read $beamtime_id`
+
 echo "db.${beamtime_id}_detector.insert({dummy:1})" | mongo  ${beamtime_id}_detector
 
 echo "Start producer"
diff --git a/tests/automatic/producer/aai/check_linux.sh b/tests/automatic/producer/aai/check_linux.sh
index eb3b7492f80da285e49aa1124b7e768b1426edfe..db89820bd85cdad1c9ebf8d1414c8f34de9c5f51 100644
--- a/tests/automatic/producer/aai/check_linux.sh
+++ b/tests/automatic/producer/aai/check_linux.sh
@@ -13,8 +13,7 @@ facility=test_facility
 year=2019
 receiver_folder=${receiver_root_folder}/${facility}/gpfs/${beamline}/${year}/data/${beamtime_id}
 receiver_folder2=${receiver_root_folder}/${facility}/gpfs/${beamline}/${year}/data/${beamtime_id2}
-token=-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4= # for bl_p07
-
+token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhbHRyaXB0MzltZTRqcXB0ZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJ3cml0ZSJ9fQ._yy0E42cOGMv81GDj3WKZJlF8mBmjKtHNDPnN5NTxvk # write token for bl_p07
 
 Cleanup() {
 	echo cleanup
diff --git a/tests/automatic/producer/aai/check_windows.bat b/tests/automatic/producer/aai/check_windows.bat
index a115afb6a12a88cb900b76d570b491ba45cc17cb..3b07ae5774d32f4319717a690e1304774f9d0233 100644
--- a/tests/automatic/producer/aai/check_windows.bat
+++ b/tests/automatic/producer/aai/check_windows.bat
@@ -8,7 +8,8 @@ SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\d
 SET receiver_folder2="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id2%"
 SET dbname=%beamtime_id%_%data_source%
 SET dbname2=%beamtime_id2%_%data_source%
-SET token=-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=
+SET token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRhbHRyaXB0MzltZTRqcXB0ZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJ3cml0ZSJ9fQ._yy0E42cOGMv81GDj3WKZJlF8mBmjKtHNDPnN5NTxvk
+
 
 echo db.%dbname%.insert({dummy:1})" | %mongo_exe% %dbname%
 
diff --git a/tests/automatic/producer/aai/settings.json.tpl.in b/tests/automatic/producer/aai/settings.json.tpl.in
index 319ef7063706b37efcbe6c62bbdadb9fe7bfe8b9..a98ad02c79c683d5be97492e6aed38a945b80f54 100644
--- a/tests/automatic/producer/aai/settings.json.tpl.in
+++ b/tests/automatic/producer/aai/settings.json.tpl.in
@@ -2,7 +2,8 @@
   "Port": {{ env "NOMAD_PORT_authorizer" }},
   "LogLevel":"debug",
   "CurrentBeamlinesFolder":"@CURRENT_BEAMLINES_FOLDER@",
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/automatic/producer_receiver/transfer_datasets/check_windows.bat b/tests/automatic/producer_receiver/transfer_datasets/check_windows.bat
index f3dd3760212d01bf26192f8c37bfbf2d6b72fda5..71219ec2eb4868eacbda8b0ca9c0121a6178f16f 100644
--- a/tests/automatic/producer_receiver/transfer_datasets/check_windows.bat
+++ b/tests/automatic/producer_receiver/transfer_datasets/check_windows.bat
@@ -11,7 +11,7 @@ call start_services.bat
 
 mkdir %receiver_folder%
 
-"%1" localhost:8400 %beamtime_id% 100 1 1 0 30 3
+"%1" 127.0.0.1:8400 %beamtime_id% 100 1 1 0 30 3
 
 ping 192.0.2.1 -n 1 -w 1000 > nul
 
diff --git a/tests/automatic/producer_receiver/transfer_single_file/check_windows.bat b/tests/automatic/producer_receiver/transfer_single_file/check_windows.bat
index e9e6e758612c236798527fc5e4b210def915b5fa..ce3967d729f3737647b4302c4e9d07994c80e9ea 100644
--- a/tests/automatic/producer_receiver/transfer_single_file/check_windows.bat
+++ b/tests/automatic/producer_receiver/transfer_single_file/check_windows.bat
@@ -11,14 +11,14 @@ call start_services.bat
 
 mkdir %receiver_folder%
 
-"%1" localhost:8400 %beamtime_id% 100 1 1 0 30
+"%1" 127.0.0.1:8400 %beamtime_id% 100 1 1 0 30
 
 ping 192.0.2.1 -n 1 -w 1000 > nul
 
 FOR /F "usebackq" %%A IN ('%receiver_folder%\processed\1') DO set size=%%~zA
 if %size% NEQ 100000 goto :error
 
-"%1" localhost:8400 wrong_id 100 1 1 0 2 2>1 | findstr /c:"authorization"  || goto :error
+"%1" 127.0.0.1:8400 wrong_id 100 1 1 0 2 2>1 | findstr /c:"authorization"  || goto :error
 
 goto :clean
 
diff --git a/tests/automatic/producer_receiver/transfer_single_file_bypass_buffer/check_windows.bat b/tests/automatic/producer_receiver/transfer_single_file_bypass_buffer/check_windows.bat
index c1d0c0e22d549aaf490acb4f59fd47832c2a3c97..7ddac5f47c1166e58d6ae55645a2cbea9ed1c07b 100644
--- a/tests/automatic/producer_receiver/transfer_single_file_bypass_buffer/check_windows.bat
+++ b/tests/automatic/producer_receiver/transfer_single_file_bypass_buffer/check_windows.bat
@@ -11,7 +11,7 @@ call start_services.bat
 
 mkdir %receiver_folder%
 
-"%1" localhost:8400 %beamtime_id% 60000 1 1 0 30
+"%1" 127.0.0.1:8400 %beamtime_id% 60000 1 1 0 30
 
 ping 192.0.2.1 -n 1 -w 1000 > nul
 
diff --git a/tests/automatic/settings/admin_token.key b/tests/automatic/settings/admin_token.key
new file mode 100644
index 0000000000000000000000000000000000000000..cdbaeda52ec8c038c904b32076ca41cd51d6ba22
--- /dev/null
+++ b/tests/automatic/settings/admin_token.key
@@ -0,0 +1 @@
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTRjNm5iaXB0M2JubW1ycjRmMCIsInN1YiI6ImFkbWluIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6ImNyZWF0ZSJ9fQ.VMSX2Bnb-BRYWoe4T5AmMFn_vBZs69iKG1YOl0kQycI
\ No newline at end of file
diff --git a/tests/automatic/settings/auth_secret_admin.key b/tests/automatic/settings/auth_secret_admin.key
new file mode 100644
index 0000000000000000000000000000000000000000..3eb59062c67f44eb713096536762d82300c1dee5
--- /dev/null
+++ b/tests/automatic/settings/auth_secret_admin.key
@@ -0,0 +1 @@
+12c2ljwewezgnea
\ 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 1c411f2b66702fe72e7b225bd1e1fe9ffb3b57ae..e3cc0585baeeb84ac5963eb14025c63f38a6a49d 100644
--- a/tests/automatic/settings/authorizer_settings.json.tpl.lin
+++ b/tests/automatic/settings/authorizer_settings.json.tpl.lin
@@ -5,7 +5,8 @@
   "beamline-path":"/tmp/asapo/receiver/files/beamline/test/current"},
   {"beamtimeId":"asapo_test1","beamline":"test1","core-path":"/tmp/asapo/receiver/files/test_facility/gpfs/test1/2019/data/asapo_test1"},
   {"beamtimeId":"asapo_test2","beamline":"test2","core-path":"/tmp/asapo/receiver/files/test_facility/gpfs/test2/2019/data/asapo_test2"}],
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
   {
diff --git a/tests/automatic/settings/authorizer_settings.json.tpl.win b/tests/automatic/settings/authorizer_settings.json.tpl.win
index e0fd183c0f8d472f991f6e64c8ae019548393ae4..31ea1eb10749c7845824160e5b5f771ab4efb485 100644
--- a/tests/automatic/settings/authorizer_settings.json.tpl.win
+++ b/tests/automatic/settings/authorizer_settings.json.tpl.win
@@ -5,7 +5,8 @@
   "beamline-path":"c:\\tmp\\asapo\\receiver\\files\\beamline\\test\\current"},
   {"beamtimeId":"asapo_test1","beamline":"test1","core-path":"c:\\tmp\\asapo\\receiver\\files\\test_facility\\gpfs\\test1\\2019\\data\\asapo_test1"},
   {"beamtimeId":"asapo_test2","beamline":"test2","core-path":"c:\\tmp\\asapo\\receiver\\files\\test_facility\\gpfs\\test2\\2019\\data\\asapo_test2"}],
-  "SecretFile":"auth_secret.key",
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key",
   "TokenDurationMin":600,
   "Ldap":
   {
diff --git a/tests/automatic/settings/broker_settings.json b/tests/automatic/settings/broker_settings.json
index a80cbbccdaa650fbfc2da3570dceb3eb392acbae..415622ce7c1ba6fe38424c139f13eb38a3acaf42 100644
--- a/tests/automatic/settings/broker_settings.json
+++ b/tests/automatic/settings/broker_settings.json
@@ -1,9 +1,9 @@
 {
   "DatabaseServer":"127.0.0.1:27017",
   "PerformanceDbServer": "localhost:8086",
+  "AuthorizationServer": "localhost:8400/asapo-authorizer",
   "PerformanceDbName": "db_test",
   "Port":5005,
   "LogLevel":"info",
-  "CheckResendInterval":0,
-  "SecretFile":"auth_secret.key"
+  "CheckResendInterval":0
 }
\ No newline at end of file
diff --git a/tests/automatic/settings/broker_settings.json.tpl b/tests/automatic/settings/broker_settings.json.tpl
index 81860d6aef6faaeb4c81bf0462500a440456ce1e..64411c9d4e1e0dc3dc5cc18820243a9901061c65 100644
--- a/tests/automatic/settings/broker_settings.json.tpl
+++ b/tests/automatic/settings/broker_settings.json.tpl
@@ -1,10 +1,10 @@
 {
   "DatabaseServer":"auto",
   "DiscoveryServer": "localhost:8400/asapo-discovery",
+  "AuthorizationServer": "localhost:8400/asapo-authorizer",
   "PerformanceDbServer": "localhost:8086",
   "CheckResendInterval":0,
   "PerformanceDbName": "db_test",
   "Port":{{ env "NOMAD_PORT_broker" }},
-  "LogLevel":"info",
-  "SecretFile":"auth_secret.key"
+  "LogLevel":"info"
 }
\ No newline at end of file
diff --git a/tests/manual/broker_debug_local/authorizer.json.tpl b/tests/manual/broker_debug_local/authorizer.json.tpl
index 9ad08b7e6111f19abd222aa13fa07abf1fb9025e..92292267951f4e5ddb9017fa3df32293531e3719 100644
--- a/tests/manual/broker_debug_local/authorizer.json.tpl
+++ b/tests/manual/broker_debug_local/authorizer.json.tpl
@@ -4,7 +4,8 @@
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test1","beamline":"test1","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test2","beamline":"test2","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/broker_debug_local/broker.json b/tests/manual/broker_debug_local/broker.json
index 11c716e064c29638fa1dc000fce31b35aece8f69..55c5f57b1e24f5d0c56b6fd4218b419f04541aa0 100644
--- a/tests/manual/broker_debug_local/broker.json
+++ b/tests/manual/broker_debug_local/broker.json
@@ -1,10 +1,10 @@
 {
   "DatabaseServer":"auto",
   "DiscoveryServer": "localhost:8400/discovery",
+  "AuthorizationServer": "localhost:8400/asapo-authorizer",
   "PerformanceDbServer": "localhost:8086",
   "CheckResendInterval":10,
   "PerformanceDbName": "db_test",
   "Port": 5005,
-  "LogLevel":"info",
-  "SecretFile":"auth_secret.key"
+  "LogLevel":"info"
 }
diff --git a/tests/manual/performance_broker/settings.json b/tests/manual/performance_broker/settings.json
index 76e84d085f3e8550ddfb0d3e54b15ff18059c116..ddeaeb916d9dacefaa70d5c2ac5b37828087b2c2 100644
--- a/tests/manual/performance_broker/settings.json
+++ b/tests/manual/performance_broker/settings.json
@@ -1,9 +1,9 @@
 {
   "DatabaseServer":"localhost:27017",
   "PerformanceDbServer": "localhost:8086",
+  "AuthorizationServer": "localhost:5007",
   "PerformanceDbName": "db_test",
   "Port":5005,
   "LogLevel":"info",
-  "CheckResendInterval":10,
-  "SecretFile":"auth_secret.key"
+  "CheckResendInterval":10
 }
\ No newline at end of file
diff --git a/tests/manual/performance_full_chain_simple/authorizer.json b/tests/manual/performance_full_chain_simple/authorizer.json
index 8400681c58b4a9f2dde30e227686e4e9388b5bc8..be04b954b994f0317372212b67886a726a25e8f8 100644
--- a/tests/manual/performance_full_chain_simple/authorizer.json
+++ b/tests/manual/performance_full_chain_simple/authorizer.json
@@ -2,7 +2,8 @@
   "Port": 5007,
   "LogLevel":"info",
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/performance_full_chain_simple/broker.json b/tests/manual/performance_full_chain_simple/broker.json
index 76e84d085f3e8550ddfb0d3e54b15ff18059c116..ddeaeb916d9dacefaa70d5c2ac5b37828087b2c2 100644
--- a/tests/manual/performance_full_chain_simple/broker.json
+++ b/tests/manual/performance_full_chain_simple/broker.json
@@ -1,9 +1,9 @@
 {
   "DatabaseServer":"localhost:27017",
   "PerformanceDbServer": "localhost:8086",
+  "AuthorizationServer": "localhost:5007",
   "PerformanceDbName": "db_test",
   "Port":5005,
   "LogLevel":"info",
-  "CheckResendInterval":10,
-  "SecretFile":"auth_secret.key"
+  "CheckResendInterval":10
 }
\ No newline at end of file
diff --git a/tests/manual/performance_producer_receiver/authorizer.json b/tests/manual/performance_producer_receiver/authorizer.json
index 8400681c58b4a9f2dde30e227686e4e9388b5bc8..be04b954b994f0317372212b67886a726a25e8f8 100644
--- a/tests/manual/performance_producer_receiver/authorizer.json
+++ b/tests/manual/performance_producer_receiver/authorizer.json
@@ -2,7 +2,8 @@
   "Port": 5007,
   "LogLevel":"info",
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/python_tests/producer/authorizer.json.tpl b/tests/manual/python_tests/producer/authorizer.json.tpl
index 9ad08b7e6111f19abd222aa13fa07abf1fb9025e..92292267951f4e5ddb9017fa3df32293531e3719 100644
--- a/tests/manual/python_tests/producer/authorizer.json.tpl
+++ b/tests/manual/python_tests/producer/authorizer.json.tpl
@@ -4,7 +4,8 @@
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test1","beamline":"test1","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test2","beamline":"test2","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/python_tests/producer_wait_bug_mongo/authorizer.json.tpl b/tests/manual/python_tests/producer_wait_bug_mongo/authorizer.json.tpl
index 9ad08b7e6111f19abd222aa13fa07abf1fb9025e..92292267951f4e5ddb9017fa3df32293531e3719 100644
--- a/tests/manual/python_tests/producer_wait_bug_mongo/authorizer.json.tpl
+++ b/tests/manual/python_tests/producer_wait_bug_mongo/authorizer.json.tpl
@@ -4,7 +4,8 @@
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test1","beamline":"test1","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test2","beamline":"test2","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/receiver_debug_local/authorizer.json.tpl b/tests/manual/receiver_debug_local/authorizer.json.tpl
index 9ad08b7e6111f19abd222aa13fa07abf1fb9025e..92292267951f4e5ddb9017fa3df32293531e3719 100644
--- a/tests/manual/receiver_debug_local/authorizer.json.tpl
+++ b/tests/manual/receiver_debug_local/authorizer.json.tpl
@@ -4,7 +4,8 @@
   "AlwaysAllowedBeamtimes":[{"beamtimeId":"asapo_test","beamline":"test","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test1","beamline":"test1","Year":"2019","Facility":"test_facility"},
   {"beamtimeId":"asapo_test2","beamline":"test2","Year":"2019","Facility":"test_facility"}],
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
 
 
diff --git a/tests/manual/receiver_debug_local/broker.json.tpl b/tests/manual/receiver_debug_local/broker.json.tpl
index 9c840220c40110c613cc41dd55d82b5704311823..7b55f51c9a8f9cf13cea1042afb80dac1b8739db 100644
--- a/tests/manual/receiver_debug_local/broker.json.tpl
+++ b/tests/manual/receiver_debug_local/broker.json.tpl
@@ -6,5 +6,6 @@
   "Port":{{ env "NOMAD_PORT_broker" }},
   "LogLevel":"info",
   "CheckResendInterval":10,
-  "SecretFile":"auth_secret.key"
+  "UserSecretFile":"auth_secret.key",
+  "AdminSecretFile":"auth_secret_admin.key"
 }
\ No newline at end of file